1a9643ea8Slogwang /* 2a9643ea8Slogwang * Copyright (c) 2013 Patrick Kelsey. All rights reserved. 3a9643ea8Slogwang * Copyright (C) 2017 THL A29 Limited, a Tencent company. 4a9643ea8Slogwang * All rights reserved. 5a9643ea8Slogwang * 6a9643ea8Slogwang * Redistribution and use in source and binary forms, with or without 7a9643ea8Slogwang * modification, are permitted provided that the following conditions are met: 8a9643ea8Slogwang * 9a9643ea8Slogwang * 1. Redistributions of source code must retain the above copyright notice, this 10a9643ea8Slogwang * list of conditions and the following disclaimer. 11a9643ea8Slogwang * 2. Redistributions in binary form must reproduce the above copyright notice, 12a9643ea8Slogwang * this list of conditions and the following disclaimer in the documentation 13a9643ea8Slogwang * and/or other materials provided with the distribution. 14a9643ea8Slogwang * 15a9643ea8Slogwang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16a9643ea8Slogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17a9643ea8Slogwang * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18a9643ea8Slogwang * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19a9643ea8Slogwang * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20a9643ea8Slogwang * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21a9643ea8Slogwang * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22a9643ea8Slogwang * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23a9643ea8Slogwang * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24a9643ea8Slogwang * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25a9643ea8Slogwang * 26a9643ea8Slogwang * Derived in part from libuinet's uinet_host_interface.c. 27a9643ea8Slogwang */ 28a9643ea8Slogwang 29a9643ea8Slogwang #include <assert.h> 30a9643ea8Slogwang #include <errno.h> 31a9643ea8Slogwang #include <string.h> 32a9643ea8Slogwang #include <stdarg.h> 33a9643ea8Slogwang #include <stdint.h> 34a9643ea8Slogwang #include <stdio.h> 35a9643ea8Slogwang #include <stdlib.h> 36a9643ea8Slogwang #include <sys/mman.h> 37a9643ea8Slogwang #include <sys/stat.h> 38a9643ea8Slogwang #include <pthread.h> 39a9643ea8Slogwang #include <sched.h> 40a9643ea8Slogwang #include <time.h> 41a9643ea8Slogwang 42a9643ea8Slogwang #include <openssl/rand.h> 43a9643ea8Slogwang #include <rte_malloc.h> 44a9643ea8Slogwang 45a9643ea8Slogwang #include "ff_host_interface.h" 46a9643ea8Slogwang #include "ff_errno.h" 47a9643ea8Slogwang 487e048838Slogwang static struct timespec current_ts; 497e048838Slogwang 50a9643ea8Slogwang void * 51a9643ea8Slogwang ff_mmap(void *addr, uint64_t len, int prot, int flags, int fd, uint64_t offset) 52a9643ea8Slogwang { 53a9643ea8Slogwang //return rte_malloc("", len, 4096); 54a9643ea8Slogwang int host_prot; 55a9643ea8Slogwang int host_flags; 56a9643ea8Slogwang 57a9643ea8Slogwang assert(ff_PROT_NONE == PROT_NONE); 58a9643ea8Slogwang host_prot = 0; 59a9643ea8Slogwang if ((prot & ff_PROT_READ) == ff_PROT_READ) host_prot |= PROT_READ; 60a9643ea8Slogwang if ((prot & ff_PROT_WRITE) == ff_PROT_WRITE) host_prot |= PROT_WRITE; 61a9643ea8Slogwang 62a9643ea8Slogwang host_flags = 0; 63a9643ea8Slogwang if ((flags & ff_MAP_SHARED) == ff_MAP_SHARED) host_flags |= MAP_SHARED; 64a9643ea8Slogwang if ((flags & ff_MAP_PRIVATE) == ff_MAP_PRIVATE) host_flags |= MAP_PRIVATE; 65a9643ea8Slogwang if ((flags & ff_MAP_ANON) == ff_MAP_ANON) host_flags |= MAP_ANON; 66a9643ea8Slogwang 67a9643ea8Slogwang void *ret = (mmap(addr, len, host_prot, host_flags, fd, offset)); 68a9643ea8Slogwang 69a9643ea8Slogwang if ((uint64_t)ret == -1) { 70a9643ea8Slogwang printf("fst mmap failed:%s\n", strerror(errno)); 71a9643ea8Slogwang exit(1); 72a9643ea8Slogwang } 73a9643ea8Slogwang return ret; 74a9643ea8Slogwang } 75a9643ea8Slogwang 76a9643ea8Slogwang int 77a9643ea8Slogwang ff_munmap(void *addr, uint64_t len) 78a9643ea8Slogwang { 79a9643ea8Slogwang //rte_free(addr); 80a9643ea8Slogwang //return 0; 81a9643ea8Slogwang return (munmap(addr, len)); 82a9643ea8Slogwang } 83a9643ea8Slogwang 84a9643ea8Slogwang 85a9643ea8Slogwang void * 86a9643ea8Slogwang ff_malloc(uint64_t size) 87a9643ea8Slogwang { 88a9643ea8Slogwang //return rte_malloc("", size, 0); 89a9643ea8Slogwang return (malloc(size)); 90a9643ea8Slogwang } 91a9643ea8Slogwang 92a9643ea8Slogwang 93a9643ea8Slogwang void * 94a9643ea8Slogwang ff_calloc(uint64_t number, uint64_t size) 95a9643ea8Slogwang { 96a9643ea8Slogwang //return rte_calloc("", number, size, 0); 97a9643ea8Slogwang return (calloc(number, size)); 98a9643ea8Slogwang } 99a9643ea8Slogwang 100a9643ea8Slogwang 101a9643ea8Slogwang void * 102a9643ea8Slogwang ff_realloc(void *p, uint64_t size) 103a9643ea8Slogwang { 104a9643ea8Slogwang if (size) { 105a9643ea8Slogwang //return rte_realloc(p, size, 0); 106a9643ea8Slogwang return (realloc(p, size)); 107a9643ea8Slogwang } 108a9643ea8Slogwang 109a9643ea8Slogwang return (p); 110a9643ea8Slogwang } 111a9643ea8Slogwang 112a9643ea8Slogwang 113a9643ea8Slogwang void 114a9643ea8Slogwang ff_free(void *p) 115a9643ea8Slogwang { 116a9643ea8Slogwang //rte_free(p); 117a9643ea8Slogwang free(p); 118a9643ea8Slogwang } 119a9643ea8Slogwang 120a9643ea8Slogwang void panic(const char *, ...) __attribute__((__noreturn__)); 121a9643ea8Slogwang 122a9643ea8Slogwang const char *panicstr = NULL; 123a9643ea8Slogwang 124a9643ea8Slogwang void 125a9643ea8Slogwang panic(const char *fmt, ...) 126a9643ea8Slogwang { 127a9643ea8Slogwang va_list ap; 128a9643ea8Slogwang 129a9643ea8Slogwang va_start(ap, fmt); 130a9643ea8Slogwang vprintf(fmt, ap); 131a9643ea8Slogwang va_end(ap); 132a9643ea8Slogwang 133a9643ea8Slogwang abort(); 134a9643ea8Slogwang } 135a9643ea8Slogwang 136a9643ea8Slogwang void 137a9643ea8Slogwang ff_clock_gettime(int id, int64_t *sec, long *nsec) 138a9643ea8Slogwang { 139a9643ea8Slogwang struct timespec ts; 140a9643ea8Slogwang int host_id; 141a9643ea8Slogwang int rv; 142a9643ea8Slogwang 143a9643ea8Slogwang switch (id) { 144a9643ea8Slogwang case ff_CLOCK_REALTIME: 145a9643ea8Slogwang host_id = CLOCK_REALTIME; 146a9643ea8Slogwang break; 147a9643ea8Slogwang #ifdef CLOCK_MONOTONIC_FAST 148a9643ea8Slogwang case ff_CLOCK_MONOTONIC_FAST: 149a9643ea8Slogwang host_id = CLOCK_MONOTONIC_FAST; 150a9643ea8Slogwang break; 151a9643ea8Slogwang #endif 152a9643ea8Slogwang case ff_CLOCK_MONOTONIC: 153a9643ea8Slogwang default: 154a9643ea8Slogwang host_id = CLOCK_MONOTONIC; 155a9643ea8Slogwang break; 156a9643ea8Slogwang } 157a9643ea8Slogwang 158a9643ea8Slogwang rv = clock_gettime(host_id, &ts); 159a9643ea8Slogwang assert(0 == rv); 160a9643ea8Slogwang 161a9643ea8Slogwang *sec = (int64_t)ts.tv_sec; 162a9643ea8Slogwang *nsec = (long)ts.tv_nsec; 163a9643ea8Slogwang } 164a9643ea8Slogwang 165a9643ea8Slogwang uint64_t 166a9643ea8Slogwang ff_clock_gettime_ns(int id) 167a9643ea8Slogwang { 168a9643ea8Slogwang int64_t sec; 169a9643ea8Slogwang long nsec; 170a9643ea8Slogwang 171a9643ea8Slogwang ff_clock_gettime(id, &sec, &nsec); 172a9643ea8Slogwang 173a9643ea8Slogwang return ((uint64_t)sec * ff_NSEC_PER_SEC + nsec); 174a9643ea8Slogwang } 175a9643ea8Slogwang 1767e048838Slogwang void 1777e048838Slogwang ff_get_current_time(time_t *sec, long *nsec) 178a9643ea8Slogwang { 17939be5a50Slogwang if (sec) { 1807e048838Slogwang *sec = current_ts.tv_sec; 18139be5a50Slogwang } 18239be5a50Slogwang 18339be5a50Slogwang if (nsec) { 1847e048838Slogwang *nsec = current_ts.tv_nsec; 185a9643ea8Slogwang } 18639be5a50Slogwang } 187a9643ea8Slogwang 1887e048838Slogwang void 1897e048838Slogwang ff_update_current_ts() 1907e048838Slogwang { 19140600211Slogwang int rv = clock_gettime(CLOCK_REALTIME, ¤t_ts); 1927e048838Slogwang assert(rv == 0); 193a9643ea8Slogwang } 194a9643ea8Slogwang 195a9643ea8Slogwang void 196a9643ea8Slogwang ff_arc4rand(void *ptr, unsigned int len, int reseed) 197a9643ea8Slogwang { 198a9643ea8Slogwang (void)reseed; 199a9643ea8Slogwang 200*b3aff0baSwhl739 RAND_bytes(ptr, len); 201a9643ea8Slogwang } 202a9643ea8Slogwang 203a9643ea8Slogwang uint32_t 204a9643ea8Slogwang ff_arc4random(void) 205a9643ea8Slogwang { 206a9643ea8Slogwang uint32_t ret; 207a9643ea8Slogwang ff_arc4rand(&ret, sizeof ret, 0); 208a9643ea8Slogwang return ret; 209a9643ea8Slogwang } 210a9643ea8Slogwang 211a9643ea8Slogwang int ff_setenv(const char *name, const char *value) 212a9643ea8Slogwang { 213a9643ea8Slogwang return setenv(name, value, 1); 214a9643ea8Slogwang } 215a9643ea8Slogwang 216a9643ea8Slogwang char *ff_getenv(const char *name) 217a9643ea8Slogwang { 218a9643ea8Slogwang return getenv(name); 219a9643ea8Slogwang } 220a9643ea8Slogwang 221a9643ea8Slogwang void ff_os_errno(int error) 222a9643ea8Slogwang { 223a9643ea8Slogwang switch (error) { 224a9643ea8Slogwang case ff_EPERM: errno = EPERM; break; 225a9643ea8Slogwang case ff_ENOENT: errno = ENOENT; break; 226a9643ea8Slogwang case ff_ESRCH: errno = ESRCH; break; 227a9643ea8Slogwang case ff_EINTR: errno = EINTR; break; 228a9643ea8Slogwang case ff_EIO: errno = EIO; break; 229a9643ea8Slogwang case ff_ENXIO: errno = ENXIO; break; 230a9643ea8Slogwang case ff_E2BIG: errno = E2BIG; break; 231a9643ea8Slogwang case ff_ENOEXEC: errno = ENOEXEC; break; 232a9643ea8Slogwang case ff_EBADF: errno = EBADF; break; 233a9643ea8Slogwang case ff_ECHILD: errno = ECHILD; break; 234a9643ea8Slogwang case ff_EDEADLK: errno = EDEADLK; break; 235a9643ea8Slogwang case ff_ENOMEM: errno = ENOMEM; break; 236a9643ea8Slogwang case ff_EACCES: errno = EACCES; break; 237a9643ea8Slogwang case ff_EFAULT: errno = EFAULT; break; 238a9643ea8Slogwang case ff_ENOTBLK: errno = ENOTBLK; break; 239a9643ea8Slogwang case ff_EBUSY: errno = EBUSY; break; 240a9643ea8Slogwang case ff_EEXIST: errno = EEXIST; break; 241a9643ea8Slogwang case ff_EXDEV: errno = EXDEV; break; 242a9643ea8Slogwang case ff_ENODEV: errno = ENODEV; break; 243a9643ea8Slogwang case ff_ENOTDIR: errno = ENOTDIR; break; 244a9643ea8Slogwang case ff_EISDIR: errno = EISDIR; break; 245a9643ea8Slogwang case ff_EINVAL: errno = EINVAL; break; 246a9643ea8Slogwang case ff_ENFILE: errno = ENFILE; break; 247a9643ea8Slogwang case ff_EMFILE: errno = EMFILE; break; 248a9643ea8Slogwang case ff_ENOTTY: errno = ENOTTY; break; 249a9643ea8Slogwang case ff_ETXTBSY: errno = ETXTBSY; break; 250a9643ea8Slogwang case ff_EFBIG: errno = EFBIG; break; 251a9643ea8Slogwang case ff_ENOSPC: errno = ENOSPC; break; 252a9643ea8Slogwang case ff_ESPIPE: errno = ESPIPE; break; 253a9643ea8Slogwang case ff_EROFS: errno = EROFS; break; 254a9643ea8Slogwang case ff_EMLINK: errno = EMLINK; break; 255a9643ea8Slogwang case ff_EPIPE: errno = EPIPE; break; 256a9643ea8Slogwang case ff_EDOM: errno = EDOM; break; 257a9643ea8Slogwang case ff_ERANGE: errno = ERANGE; break; 258a9643ea8Slogwang 259a9643ea8Slogwang /* case ff_EAGAIN: same as EWOULDBLOCK */ 260a9643ea8Slogwang case ff_EWOULDBLOCK: errno = EWOULDBLOCK; break; 261a9643ea8Slogwang 262a9643ea8Slogwang case ff_EINPROGRESS: errno = EINPROGRESS; break; 263a9643ea8Slogwang case ff_EALREADY: errno = EALREADY; break; 264a9643ea8Slogwang case ff_ENOTSOCK: errno = ENOTSOCK; break; 265a9643ea8Slogwang case ff_EDESTADDRREQ: errno = EDESTADDRREQ; break; 266a9643ea8Slogwang case ff_EMSGSIZE: errno = EMSGSIZE; break; 267a9643ea8Slogwang case ff_EPROTOTYPE: errno = EPROTOTYPE; break; 268a9643ea8Slogwang case ff_ENOPROTOOPT: errno = ENOPROTOOPT; break; 269a9643ea8Slogwang case ff_EPROTONOSUPPORT: errno = EPROTONOSUPPORT; break; 270a9643ea8Slogwang case ff_ESOCKTNOSUPPORT: errno = ESOCKTNOSUPPORT; break; 271a9643ea8Slogwang 272a9643ea8Slogwang /* case ff_EOPNOTSUPP: same as ENOTSUP */ 273a9643ea8Slogwang case ff_ENOTSUP: errno = ENOTSUP; break; 274a9643ea8Slogwang 275a9643ea8Slogwang case ff_EPFNOSUPPORT: errno = EPFNOSUPPORT; break; 276a9643ea8Slogwang case ff_EAFNOSUPPORT: errno = EAFNOSUPPORT; break; 277a9643ea8Slogwang case ff_EADDRINUSE: errno = EADDRINUSE; break; 278a9643ea8Slogwang case ff_EADDRNOTAVAIL: errno = EADDRNOTAVAIL; break; 279a9643ea8Slogwang case ff_ENETDOWN: errno = ENETDOWN; break; 280a9643ea8Slogwang case ff_ENETUNREACH: errno = ENETUNREACH; break; 281a9643ea8Slogwang case ff_ENETRESET: errno = ENETRESET; break; 282a9643ea8Slogwang case ff_ECONNABORTED: errno = ECONNABORTED; break; 283a9643ea8Slogwang case ff_ECONNRESET: errno = ECONNRESET; break; 284a9643ea8Slogwang case ff_ENOBUFS: errno = ENOBUFS; break; 285a9643ea8Slogwang case ff_EISCONN: errno = EISCONN; break; 286a9643ea8Slogwang case ff_ENOTCONN: errno = ENOTCONN; break; 287a9643ea8Slogwang case ff_ESHUTDOWN: errno = ESHUTDOWN; break; 288a9643ea8Slogwang case ff_ETOOMANYREFS: errno = ETOOMANYREFS; break; 289a9643ea8Slogwang case ff_ETIMEDOUT: errno = ETIMEDOUT; break; 290a9643ea8Slogwang case ff_ECONNREFUSED: errno = ECONNREFUSED; break; 291a9643ea8Slogwang case ff_ELOOP: errno = ELOOP; break; 292a9643ea8Slogwang case ff_ENAMETOOLONG: errno = ENAMETOOLONG; break; 293a9643ea8Slogwang case ff_EHOSTDOWN: errno = EHOSTDOWN; break; 294a9643ea8Slogwang case ff_EHOSTUNREACH: errno = EHOSTUNREACH; break; 295a9643ea8Slogwang case ff_ENOTEMPTY: errno = ENOTEMPTY; break; 296a9643ea8Slogwang case ff_EUSERS: errno = EUSERS; break; 297a9643ea8Slogwang case ff_EDQUOT: errno = EDQUOT; break; 298a9643ea8Slogwang case ff_ESTALE: errno = ESTALE; break; 299a9643ea8Slogwang case ff_EREMOTE: errno = EREMOTE; break; 300a9643ea8Slogwang case ff_ENOLCK: errno = ENOLCK; break; 301a9643ea8Slogwang case ff_ENOSYS: errno = ENOSYS; break; 302a9643ea8Slogwang case ff_EIDRM: errno = EIDRM; break; 303a9643ea8Slogwang case ff_ENOMSG: errno = ENOMSG; break; 304a9643ea8Slogwang case ff_EOVERFLOW: errno = EOVERFLOW; break; 305a9643ea8Slogwang case ff_ECANCELED: errno = ECANCELED; break; 306a9643ea8Slogwang case ff_EILSEQ: errno = EILSEQ; break; 307a9643ea8Slogwang case ff_EBADMSG: errno = EBADMSG; break; 308a9643ea8Slogwang case ff_EMULTIHOP: errno = EMULTIHOP; break; 309a9643ea8Slogwang case ff_ENOLINK: errno = ENOLINK; break; 310a9643ea8Slogwang case ff_EPROTO: errno = EPROTO; break; 311a9643ea8Slogwang default: errno = error; break; 312a9643ea8Slogwang } 313a9643ea8Slogwang 314a9643ea8Slogwang } 315a9643ea8Slogwang 316