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; 49*ef5ab859S10077240 extern void* ff_mem_get_page(); 50*ef5ab859S10077240 extern int ff_mem_free_addr(void* p); 517e048838Slogwang 52a9643ea8Slogwang void * 53a9643ea8Slogwang ff_mmap(void *addr, uint64_t len, int prot, int flags, int fd, uint64_t offset) 54a9643ea8Slogwang { 55a9643ea8Slogwang //return rte_malloc("", len, 4096); 56a9643ea8Slogwang int host_prot; 57a9643ea8Slogwang int host_flags; 58a9643ea8Slogwang 59*ef5ab859S10077240 #ifdef _USE_PAGE_ARRAY_ 60*ef5ab859S10077240 if( len == 4096 ) 61*ef5ab859S10077240 { 62*ef5ab859S10077240 return ff_mem_get_page(); 63*ef5ab859S10077240 } 64*ef5ab859S10077240 else 65*ef5ab859S10077240 #endif 66*ef5ab859S10077240 { 67*ef5ab859S10077240 68a9643ea8Slogwang assert(ff_PROT_NONE == PROT_NONE); 69a9643ea8Slogwang host_prot = 0; 70a9643ea8Slogwang if ((prot & ff_PROT_READ) == ff_PROT_READ) host_prot |= PROT_READ; 71a9643ea8Slogwang if ((prot & ff_PROT_WRITE) == ff_PROT_WRITE) host_prot |= PROT_WRITE; 72a9643ea8Slogwang 73a9643ea8Slogwang host_flags = 0; 74a9643ea8Slogwang if ((flags & ff_MAP_SHARED) == ff_MAP_SHARED) host_flags |= MAP_SHARED; 75a9643ea8Slogwang if ((flags & ff_MAP_PRIVATE) == ff_MAP_PRIVATE) host_flags |= MAP_PRIVATE; 76a9643ea8Slogwang if ((flags & ff_MAP_ANON) == ff_MAP_ANON) host_flags |= MAP_ANON; 77a9643ea8Slogwang 78a9643ea8Slogwang void *ret = (mmap(addr, len, host_prot, host_flags, fd, offset)); 79a9643ea8Slogwang 80a9643ea8Slogwang if ((uint64_t)ret == -1) { 81a9643ea8Slogwang printf("fst mmap failed:%s\n", strerror(errno)); 82a9643ea8Slogwang exit(1); 83a9643ea8Slogwang } 84a9643ea8Slogwang return ret; 85a9643ea8Slogwang } 86*ef5ab859S10077240 } 87a9643ea8Slogwang 88a9643ea8Slogwang int 89a9643ea8Slogwang ff_munmap(void *addr, uint64_t len) 90a9643ea8Slogwang { 91*ef5ab859S10077240 #ifdef _USE_PAGE_ARRAY_ 92*ef5ab859S10077240 if ( len == 4096 ) 93*ef5ab859S10077240 { 94*ef5ab859S10077240 return ff_mem_free_addr(addr); 95*ef5ab859S10077240 } 96*ef5ab859S10077240 #endif 97a9643ea8Slogwang //rte_free(addr); 98a9643ea8Slogwang //return 0; 99a9643ea8Slogwang return (munmap(addr, len)); 100a9643ea8Slogwang } 101a9643ea8Slogwang 102a9643ea8Slogwang 103a9643ea8Slogwang void * 104a9643ea8Slogwang ff_malloc(uint64_t size) 105a9643ea8Slogwang { 106a9643ea8Slogwang //return rte_malloc("", size, 0); 107a9643ea8Slogwang return (malloc(size)); 108a9643ea8Slogwang } 109a9643ea8Slogwang 110a9643ea8Slogwang 111a9643ea8Slogwang void * 112a9643ea8Slogwang ff_calloc(uint64_t number, uint64_t size) 113a9643ea8Slogwang { 114a9643ea8Slogwang //return rte_calloc("", number, size, 0); 115a9643ea8Slogwang return (calloc(number, size)); 116a9643ea8Slogwang } 117a9643ea8Slogwang 118a9643ea8Slogwang 119a9643ea8Slogwang void * 120a9643ea8Slogwang ff_realloc(void *p, uint64_t size) 121a9643ea8Slogwang { 122a9643ea8Slogwang if (size) { 123a9643ea8Slogwang //return rte_realloc(p, size, 0); 124a9643ea8Slogwang return (realloc(p, size)); 125a9643ea8Slogwang } 126a9643ea8Slogwang 127a9643ea8Slogwang return (p); 128a9643ea8Slogwang } 129a9643ea8Slogwang 130a9643ea8Slogwang 131a9643ea8Slogwang void 132a9643ea8Slogwang ff_free(void *p) 133a9643ea8Slogwang { 134a9643ea8Slogwang //rte_free(p); 135a9643ea8Slogwang free(p); 136a9643ea8Slogwang } 137a9643ea8Slogwang 138a9643ea8Slogwang void panic(const char *, ...) __attribute__((__noreturn__)); 139a9643ea8Slogwang 140a9643ea8Slogwang const char *panicstr = NULL; 141a9643ea8Slogwang 142a9643ea8Slogwang void 143a9643ea8Slogwang panic(const char *fmt, ...) 144a9643ea8Slogwang { 145a9643ea8Slogwang va_list ap; 146a9643ea8Slogwang 147a9643ea8Slogwang va_start(ap, fmt); 148a9643ea8Slogwang vprintf(fmt, ap); 149a9643ea8Slogwang va_end(ap); 150a9643ea8Slogwang 151a9643ea8Slogwang abort(); 152a9643ea8Slogwang } 153a9643ea8Slogwang 154a9643ea8Slogwang void 155a9643ea8Slogwang ff_clock_gettime(int id, int64_t *sec, long *nsec) 156a9643ea8Slogwang { 157a9643ea8Slogwang struct timespec ts; 158a9643ea8Slogwang int host_id; 159a9643ea8Slogwang int rv; 160a9643ea8Slogwang 161a9643ea8Slogwang switch (id) { 162a9643ea8Slogwang case ff_CLOCK_REALTIME: 163a9643ea8Slogwang host_id = CLOCK_REALTIME; 164a9643ea8Slogwang break; 165a9643ea8Slogwang #ifdef CLOCK_MONOTONIC_FAST 166a9643ea8Slogwang case ff_CLOCK_MONOTONIC_FAST: 167a9643ea8Slogwang host_id = CLOCK_MONOTONIC_FAST; 168a9643ea8Slogwang break; 169a9643ea8Slogwang #endif 170a9643ea8Slogwang case ff_CLOCK_MONOTONIC: 171a9643ea8Slogwang default: 172a9643ea8Slogwang host_id = CLOCK_MONOTONIC; 173a9643ea8Slogwang break; 174a9643ea8Slogwang } 175a9643ea8Slogwang 176a9643ea8Slogwang rv = clock_gettime(host_id, &ts); 177a9643ea8Slogwang assert(0 == rv); 178a9643ea8Slogwang 179a9643ea8Slogwang *sec = (int64_t)ts.tv_sec; 180a9643ea8Slogwang *nsec = (long)ts.tv_nsec; 181a9643ea8Slogwang } 182a9643ea8Slogwang 183a9643ea8Slogwang uint64_t 184a9643ea8Slogwang ff_clock_gettime_ns(int id) 185a9643ea8Slogwang { 186a9643ea8Slogwang int64_t sec; 187a9643ea8Slogwang long nsec; 188a9643ea8Slogwang 189a9643ea8Slogwang ff_clock_gettime(id, &sec, &nsec); 190a9643ea8Slogwang 191a9643ea8Slogwang return ((uint64_t)sec * ff_NSEC_PER_SEC + nsec); 192a9643ea8Slogwang } 193a9643ea8Slogwang 1947e048838Slogwang void 1957e048838Slogwang ff_get_current_time(time_t *sec, long *nsec) 196a9643ea8Slogwang { 19739be5a50Slogwang if (sec) { 1987e048838Slogwang *sec = current_ts.tv_sec; 19939be5a50Slogwang } 20039be5a50Slogwang 20139be5a50Slogwang if (nsec) { 2027e048838Slogwang *nsec = current_ts.tv_nsec; 203a9643ea8Slogwang } 20439be5a50Slogwang } 205a9643ea8Slogwang 2067e048838Slogwang void 2077e048838Slogwang ff_update_current_ts() 2087e048838Slogwang { 20940600211Slogwang int rv = clock_gettime(CLOCK_REALTIME, ¤t_ts); 2107e048838Slogwang assert(rv == 0); 211a9643ea8Slogwang } 212a9643ea8Slogwang 213a9643ea8Slogwang void 214a9643ea8Slogwang ff_arc4rand(void *ptr, unsigned int len, int reseed) 215a9643ea8Slogwang { 216a9643ea8Slogwang (void)reseed; 217a9643ea8Slogwang 218b3aff0baSwhl739 RAND_bytes(ptr, len); 219a9643ea8Slogwang } 220a9643ea8Slogwang 221a9643ea8Slogwang uint32_t 222a9643ea8Slogwang ff_arc4random(void) 223a9643ea8Slogwang { 224a9643ea8Slogwang uint32_t ret; 225a9643ea8Slogwang ff_arc4rand(&ret, sizeof ret, 0); 226a9643ea8Slogwang return ret; 227a9643ea8Slogwang } 228a9643ea8Slogwang 229a9643ea8Slogwang int ff_setenv(const char *name, const char *value) 230a9643ea8Slogwang { 231a9643ea8Slogwang return setenv(name, value, 1); 232a9643ea8Slogwang } 233a9643ea8Slogwang 234a9643ea8Slogwang char *ff_getenv(const char *name) 235a9643ea8Slogwang { 236a9643ea8Slogwang return getenv(name); 237a9643ea8Slogwang } 238a9643ea8Slogwang 239a9643ea8Slogwang void ff_os_errno(int error) 240a9643ea8Slogwang { 241a9643ea8Slogwang switch (error) { 242a9643ea8Slogwang case ff_EPERM: errno = EPERM; break; 243a9643ea8Slogwang case ff_ENOENT: errno = ENOENT; break; 244a9643ea8Slogwang case ff_ESRCH: errno = ESRCH; break; 245a9643ea8Slogwang case ff_EINTR: errno = EINTR; break; 246a9643ea8Slogwang case ff_EIO: errno = EIO; break; 247a9643ea8Slogwang case ff_ENXIO: errno = ENXIO; break; 248a9643ea8Slogwang case ff_E2BIG: errno = E2BIG; break; 249a9643ea8Slogwang case ff_ENOEXEC: errno = ENOEXEC; break; 250a9643ea8Slogwang case ff_EBADF: errno = EBADF; break; 251a9643ea8Slogwang case ff_ECHILD: errno = ECHILD; break; 252a9643ea8Slogwang case ff_EDEADLK: errno = EDEADLK; break; 253a9643ea8Slogwang case ff_ENOMEM: errno = ENOMEM; break; 254a9643ea8Slogwang case ff_EACCES: errno = EACCES; break; 255a9643ea8Slogwang case ff_EFAULT: errno = EFAULT; break; 256a9643ea8Slogwang case ff_ENOTBLK: errno = ENOTBLK; break; 257a9643ea8Slogwang case ff_EBUSY: errno = EBUSY; break; 258a9643ea8Slogwang case ff_EEXIST: errno = EEXIST; break; 259a9643ea8Slogwang case ff_EXDEV: errno = EXDEV; break; 260a9643ea8Slogwang case ff_ENODEV: errno = ENODEV; break; 261a9643ea8Slogwang case ff_ENOTDIR: errno = ENOTDIR; break; 262a9643ea8Slogwang case ff_EISDIR: errno = EISDIR; break; 263a9643ea8Slogwang case ff_EINVAL: errno = EINVAL; break; 264a9643ea8Slogwang case ff_ENFILE: errno = ENFILE; break; 265a9643ea8Slogwang case ff_EMFILE: errno = EMFILE; break; 266a9643ea8Slogwang case ff_ENOTTY: errno = ENOTTY; break; 267a9643ea8Slogwang case ff_ETXTBSY: errno = ETXTBSY; break; 268a9643ea8Slogwang case ff_EFBIG: errno = EFBIG; break; 269a9643ea8Slogwang case ff_ENOSPC: errno = ENOSPC; break; 270a9643ea8Slogwang case ff_ESPIPE: errno = ESPIPE; break; 271a9643ea8Slogwang case ff_EROFS: errno = EROFS; break; 272a9643ea8Slogwang case ff_EMLINK: errno = EMLINK; break; 273a9643ea8Slogwang case ff_EPIPE: errno = EPIPE; break; 274a9643ea8Slogwang case ff_EDOM: errno = EDOM; break; 275a9643ea8Slogwang case ff_ERANGE: errno = ERANGE; break; 276a9643ea8Slogwang 277a9643ea8Slogwang /* case ff_EAGAIN: same as EWOULDBLOCK */ 278a9643ea8Slogwang case ff_EWOULDBLOCK: errno = EWOULDBLOCK; break; 279a9643ea8Slogwang 280a9643ea8Slogwang case ff_EINPROGRESS: errno = EINPROGRESS; break; 281a9643ea8Slogwang case ff_EALREADY: errno = EALREADY; break; 282a9643ea8Slogwang case ff_ENOTSOCK: errno = ENOTSOCK; break; 283a9643ea8Slogwang case ff_EDESTADDRREQ: errno = EDESTADDRREQ; break; 284a9643ea8Slogwang case ff_EMSGSIZE: errno = EMSGSIZE; break; 285a9643ea8Slogwang case ff_EPROTOTYPE: errno = EPROTOTYPE; break; 286a9643ea8Slogwang case ff_ENOPROTOOPT: errno = ENOPROTOOPT; break; 287a9643ea8Slogwang case ff_EPROTONOSUPPORT: errno = EPROTONOSUPPORT; break; 288a9643ea8Slogwang case ff_ESOCKTNOSUPPORT: errno = ESOCKTNOSUPPORT; break; 289a9643ea8Slogwang 290a9643ea8Slogwang /* case ff_EOPNOTSUPP: same as ENOTSUP */ 291a9643ea8Slogwang case ff_ENOTSUP: errno = ENOTSUP; break; 292a9643ea8Slogwang 293a9643ea8Slogwang case ff_EPFNOSUPPORT: errno = EPFNOSUPPORT; break; 294a9643ea8Slogwang case ff_EAFNOSUPPORT: errno = EAFNOSUPPORT; break; 295a9643ea8Slogwang case ff_EADDRINUSE: errno = EADDRINUSE; break; 296a9643ea8Slogwang case ff_EADDRNOTAVAIL: errno = EADDRNOTAVAIL; break; 297a9643ea8Slogwang case ff_ENETDOWN: errno = ENETDOWN; break; 298a9643ea8Slogwang case ff_ENETUNREACH: errno = ENETUNREACH; break; 299a9643ea8Slogwang case ff_ENETRESET: errno = ENETRESET; break; 300a9643ea8Slogwang case ff_ECONNABORTED: errno = ECONNABORTED; break; 301a9643ea8Slogwang case ff_ECONNRESET: errno = ECONNRESET; break; 302a9643ea8Slogwang case ff_ENOBUFS: errno = ENOBUFS; break; 303a9643ea8Slogwang case ff_EISCONN: errno = EISCONN; break; 304a9643ea8Slogwang case ff_ENOTCONN: errno = ENOTCONN; break; 305a9643ea8Slogwang case ff_ESHUTDOWN: errno = ESHUTDOWN; break; 306a9643ea8Slogwang case ff_ETOOMANYREFS: errno = ETOOMANYREFS; break; 307a9643ea8Slogwang case ff_ETIMEDOUT: errno = ETIMEDOUT; break; 308a9643ea8Slogwang case ff_ECONNREFUSED: errno = ECONNREFUSED; break; 309a9643ea8Slogwang case ff_ELOOP: errno = ELOOP; break; 310a9643ea8Slogwang case ff_ENAMETOOLONG: errno = ENAMETOOLONG; break; 311a9643ea8Slogwang case ff_EHOSTDOWN: errno = EHOSTDOWN; break; 312a9643ea8Slogwang case ff_EHOSTUNREACH: errno = EHOSTUNREACH; break; 313a9643ea8Slogwang case ff_ENOTEMPTY: errno = ENOTEMPTY; break; 314a9643ea8Slogwang case ff_EUSERS: errno = EUSERS; break; 315a9643ea8Slogwang case ff_EDQUOT: errno = EDQUOT; break; 316a9643ea8Slogwang case ff_ESTALE: errno = ESTALE; break; 317a9643ea8Slogwang case ff_EREMOTE: errno = EREMOTE; break; 318a9643ea8Slogwang case ff_ENOLCK: errno = ENOLCK; break; 319a9643ea8Slogwang case ff_ENOSYS: errno = ENOSYS; break; 320a9643ea8Slogwang case ff_EIDRM: errno = EIDRM; break; 321a9643ea8Slogwang case ff_ENOMSG: errno = ENOMSG; break; 322a9643ea8Slogwang case ff_EOVERFLOW: errno = EOVERFLOW; break; 323a9643ea8Slogwang case ff_ECANCELED: errno = ECANCELED; break; 324a9643ea8Slogwang case ff_EILSEQ: errno = EILSEQ; break; 325a9643ea8Slogwang case ff_EBADMSG: errno = EBADMSG; break; 326a9643ea8Slogwang case ff_EMULTIHOP: errno = EMULTIHOP; break; 327a9643ea8Slogwang case ff_ENOLINK: errno = ENOLINK; break; 328a9643ea8Slogwang case ff_EPROTO: errno = EPROTO; break; 329a9643ea8Slogwang default: errno = error; break; 330a9643ea8Slogwang } 331a9643ea8Slogwang 332a9643ea8Slogwang } 333a9643ea8Slogwang 334