From 96d4f49ab01006d983d53f28657471696f031651 Mon Sep 17 00:00:00 2001 From: Sharan Santhanam Date: Wed, 13 Jun 2018 11:22:33 +0200 Subject: [PATCH] Initial port of lwIP to Unikraft This is our initial port of lwIP to Unikraft as external library. For now you need newlib to make it work. Signed-off-by: Simon Kuenzer Signed-off-by: Kenichi Yasukata Signed-off-by: Felipe Huici Signed-off-by: Florian Schmidt Signed-off-by: Sharan Santhanam --- Config.uk | 162 +++++++++++++++ Makefile.uk | 183 +++++++++++++++++ alloc.c | 16 ++ include/arch/cc.h | 89 +++++++++ include/arch/sys_arch.h | 47 +++++ include/lwipopts.h | 251 ++++++++++++++++++++++++ init.c | 27 +++ mailbox.c | 121 ++++++++++++ mutex.c | 40 ++++ patches/0001-timeval-for-socket-c.patch | 11 ++ semaphore.c | 56 ++++++ threads.c | 21 ++ time.c | 8 + 13 files changed, 1032 insertions(+) create mode 100644 Config.uk create mode 100644 Makefile.uk create mode 100644 alloc.c create mode 100644 include/arch/cc.h create mode 100644 include/arch/sys_arch.h create mode 100644 include/lwipopts.h create mode 100644 init.c create mode 100644 mailbox.c create mode 100644 mutex.c create mode 100644 patches/0001-timeval-for-socket-c.patch create mode 100644 semaphore.c create mode 100644 threads.c create mode 100644 time.c diff --git a/Config.uk b/Config.uk new file mode 100644 index 0000000..4becc66 --- /dev/null +++ b/Config.uk @@ -0,0 +1,162 @@ +menuconfig LIBLWIP + bool "lwip - Lightweight TCP/IP stack" + default n + select LIBNOLIBC if !HAVE_LIBC + select LIBUKDEBUG + select LIBUKMTPRIM + select LIBUKSWRAND + select LIBUKSCHED + select HAVE_NW_STACK + + select LIBLWIP_HEAPONLY + +if LIBLWIP +choice + prompt "Memory allocation mode" + default LWIP_HEAP + +config LWIP_HEAP + bool "Heap only" + +#config LWIP_POOLS +# bool "Memory pools" +endchoice + +config LWIP_IPV4 + bool "IPv4" + default y + +config LWIP_IPV6 + bool "IPv6" + default n + + +config LWIP_RXCHECKSUM + bool "Check checksum on reception" + default n + +config LWIP_TXCHECKSUM + bool "Calculate checksum on sending" + default y + +config LWIP_UDP + bool "UDP support" + default y + +menuconfig LWIP_TCP + bool "TCP support" + default y + +if LWIP_TCP +config LWIP_TCP_MSS + int "Maximum segment size (bytes)" + default 1460 + +config LWIP_WND_SCALE + bool "Window scaling" + default y + +config LWIP_TCP_KEEPALIVE + bool "Keepalive" + default n + +config LWIP_TCP_TIMESTAMPS + bool "Timestamps" + default n +endif + +config LWIP_ICMP + bool "ICMP support" + default y + +config LWIP_IGMP + bool "IGMP support" + default n + +config LWIP_SNMP + bool "SNMP support" + default n + +config LWIP_DHCP + bool "DHCP client" + depends on LWIP_IPV4 + default n + help + Query device IP address from DHCP server on network + +config LWIP_AUTOIP + bool "AutoIP" + depends on LWIP_IPV4 + default n + help + Dynamic IP address assignment at device on startup + +menuconfig LWIP_DNS + bool "DNS Resolver" + default y + +if LWIP_DNS +config LWIP_DNS_MAX_SERVERS + int "Maximum number of servers" + default 2 + +config LWIP_DNS_TABLE_SIZE + int "DNS table size" + default 32 +endif + +config LWIP_PPP + bool "Point-to-Point support" + default n + +config LWIP_SLIP + bool "SLIP netif" + default n + +config LWIP_6LOWPAN + bool "6LowPAN" + depends on LWIP_IPV6 + default n + +config LWIP_SOCKET + bool "Socket API" + default y + +menuconfig LWIP_DEBUG + bool "Debug messages" + default n + +if LWIP_DEBUG +config LWIP_MAINLOOP_DEBUG + bool "Mainloop" + default n + +config LWIP_IF_DEBUG + bool "Netif" + default n + +config LWIP_IP_DEBUG + bool "IP" + default n + +config LWIP_UDP_DEBUG + bool "UDP" + default n + +config LWIP_TCP_DEBUG + bool "TCP" + default n + +config LWIP_SYS_DEBUG + bool "System" + default n + +config LWIP_API_DEBUG + bool "API" + default n + +config LWIP_SERVICE_DEBUG + bool "Service" + default n +endif +endif diff --git a/Makefile.uk b/Makefile.uk new file mode 100644 index 0000000..b95584e --- /dev/null +++ b/Makefile.uk @@ -0,0 +1,183 @@ +# liblwip: Makefile.uk +# +# Authors: Felipe Huici +# Simon Kuenzer +# +# +# Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. +# + +################################################################################ +# Library registration +################################################################################ +$(eval $(call addlib_s,liblwip,$(LIBLWIP))) + +################################################################################ +# Sources +################################################################################ +LIBLWIP_ZIPNAME=lwip-2.0.3 +LIBLWIP_URL=http://download.savannah.nongnu.org/releases/lwip/$(LIBLWIP_ZIPNAME).zip +LIBLWIP_PATCHDIR=$(LIBLWIP_BASE)/patches +$(eval $(call fetch,liblwip,$(LIBLWIP_URL))) +$(eval $(call patch,liblwip,$(LIBLWIP_PATCHDIR),$(LIBLWIP_ZIPNAME))) + +################################################################################ +# Helpers +################################################################################ +LIBLWIP_EXTRACTED=$(LIBLWIP_ORIGIN)/$(LIBLWIP_ZIPNAME)/src + +################################################################################ +# Library includes +################################################################################ +CINCLUDES-y += -I$(LIBLWIP_BASE)/include -I$(LIBLWIP_EXTRACTED)/include +CXXINCLUDES-y += -I$(LIBLWIP_BASE)/include -I$(LIBLWIP_EXTRACTED)/include + +################################################################################ +# Global flags +################################################################################ +LIBLWIP_CFLAGS-y += -DCONFIG_LWIP_MINIMAL -ULWIP_TIMEVAL_PRIVATE + +# Suppress some warnings to make the build process look neater +LIBLWIP_SUPPRESS_CFLAGS += -Wno-unused-parameter -Wno-unused-variable \ +-Wno-unused-but-set-variable -Wno-unused-label -Wno-char-subscripts \ +-Wno-unused-function -Wno-missing-field-initializers \ +-Wno-uninitialized -Wno-array-bounds -Wno-maybe-uninitialized \ +-Wno-pointer-sign -Wno-unused-value -Wno-unused-macros \ +-Wno-parentheses -Wno-implicit-function-declaration \ +-Wno-shift-negative-value -Wno-missing-braces -Wno-endif-labels \ +-Wno-unused-but-set-variable -Wno-implicit-function-declaration \ +-Wno-unused-const-variable -Wno-type-limits -Wno-sign-compare +LIBLWIP_CFLAGS-y += $(LIBLWIP_SUPPRESS_CFLAGS) + +################################################################################ +# Core +################################################################################ +LIBLWIP_SRCS-y += $(LIBLWIP_BASE)/alloc.c|unikraft +LIBLWIP_SRCS-y += $(LIBLWIP_BASE)/mutex.c|unikraft +LIBLWIP_SRCS-y += $(LIBLWIP_BASE)/semaphore.c|unikraft +LIBLWIP_SRCS-y += $(LIBLWIP_BASE)/mailbox.c|unikraft +LIBLWIP_SRCS-y += $(LIBLWIP_BASE)/init.c|unikraft +LIBLWIP_SRCS-y += $(LIBLWIP_BASE)/threads.c|unikraft +LIBLWIP_SRCS-y += $(LIBLWIP_BASE)/time.c|unikraft +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/core/init.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/core/def.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/core/inet_chksum.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/core/ip.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/core/mem.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/core/memp.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/core/netif.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/core/pbuf.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/core/raw.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/core/stats.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/core/sys.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/core/timeouts.c +LIBLWIP_SRCS-$(LWIP_DNS) += $(LIBLWIP_EXTRACTED)/core/dns.c +LIBLWIP_SRCS-$(LWIP_TCP) += $(LIBLWIP_EXTRACTED)/core/tcp.c +LIBLWIP_SRCS-$(LWIP_TCP) += $(LIBLWIP_EXTRACTED)/core/tcp_in.c +LIBLWIP_SRCS-$(LWIP_TCP) += $(LIBLWIP_EXTRACTED)/core/tcp_out.c +LIBLWIP_SRCS-$(LWIP_UDP) += $(LIBLWIP_EXTRACTED)/core/udp.c + +################################################################################ +# APIs +################################################################################ +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/api/api_lib.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/api/api_msg.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/api/err.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/api/netbuf.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/api/netdb.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/api/netifapi.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/api/tcpip.c +LIBLWIP_SRCS-$(LWIP_SOCKET) += $(LIBLWIP_EXTRACTED)/api/sockets.c + +################################################################################ +# NETIF Helpers +################################################################################ +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/netif/ethernet.c +LIBLWIP_SRCS-$(LWIP_SLIP) += $(LIBLWIP_EXTRACTED)/netif/slipif.c +LIBLWIP_SRCS-y += $(LIBLWIP_EXTRACTED)/netif/lowpan6.c + +################################################################################ +# IPv4 +################################################################################ +LIBLWIP_SRCS-$(LWIP_AUTOIP) += $(LIBLWIP_EXTRACTED)/core/ipv4/autoip.c +LIBLWIP_SRCS-$(LWIP_DHCP) += $(LIBLWIP_EXTRACTED)/core/ipv4/dhcp.c +LIBLWIP_SRCS-$(LWIP_IPV4) += $(LIBLWIP_EXTRACTED)/core/ipv4/etharp.c +LIBLWIP_SRCS-$(LWIP_IPV4) += $(LIBLWIP_EXTRACTED)/core/ipv4/icmp.c +LIBLWIP_SRCS-$(LWIP_IPV4) += $(LIBLWIP_EXTRACTED)/core/ipv4/igmp.c +LIBLWIP_SRCS-$(LWIP_IPV4) += $(LIBLWIP_EXTRACTED)/core/ipv4/ip4_frag.c +LIBLWIP_SRCS-$(LWIP_IPV4) += $(LIBLWIP_EXTRACTED)/core/ipv4/ip4.c +LIBLWIP_SRCS-$(LWIP_IPV4) += $(LIBLWIP_EXTRACTED)/core/ipv4/ip4_addr.c + +################################################################################ +# IPv6 +################################################################################ +LIBLWIP_SRCS-$(LWIP_IPV6) += $(LIBLWIP_EXTRACTED)/core/ipv6/dhcp6.c +LIBLWIP_SRCS-$(LWIP_IPV6) += $(LIBLWIP_EXTRACTED)/core/ipv6/ethip6.c +LIBLWIP_SRCS-$(LWIP_IPV6) += $(LIBLWIP_EXTRACTED)/core/ipv6/icmp6.c +LIBLWIP_SRCS-$(LWIP_IPV6) += $(LIBLWIP_EXTRACTED)/core/ipv6/inet6.c +LIBLWIP_SRCS-$(LWIP_IPV6) += $(LIBLWIP_EXTRACTED)/core/ipv6/ip6.c +LIBLWIP_SRCS-$(LWIP_IPV6) += $(LIBLWIP_EXTRACTED)/core/ipv6/ip6_addr.c +LIBLWIP_SRCS-$(LWIP_IPV6) += $(LIBLWIP_EXTRACTED)/core/ipv6/ip6_frag.c +LIBLWIP_SRCS-$(LWIP_IPV6) += $(LIBLWIP_EXTRACTED)/core/ipv6/mld6.c +LIBLWIP_SRCS-$(LWIP_IPV6) += $(LIBLWIP_EXTRACTED)/core/ipv6/nd6.c + +################################################################################ +# Lwip code - PPP +################################################################################ +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/auth.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/ccp.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/chap-md5.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/chap_ms.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/chap-new.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/demand.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/eap.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/ecp.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/eui64.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/fsm.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/ipcp.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/ipv6cp.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/lcp.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/magic.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/mppe.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/multilink.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/ppp.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/pppapi.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/pppcrypt.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/pppoe.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/pppol2tp.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/pppos.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/upap.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/utils.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/vj.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/polarssl/arc4.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/polarssl/des.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/polarssl/md4.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/polarssl/md5.c +LIBLWIP_SRCS-$(LWIP_PPP) += $(LIBLWIP_EXTRACTED)/netif/ppp/polarssl/sha1.c diff --git a/alloc.c b/alloc.c new file mode 100644 index 0000000..86e0c6b --- /dev/null +++ b/alloc.c @@ -0,0 +1,16 @@ +#include + +void *sys_malloc(size_t size) +{ + return uk_malloc(uk_alloc_get_default(), size); +} + +void *sys_calloc(int num, size_t size) +{ + return uk_calloc(uk_alloc_get_default(), num, size); +} + +void sys_free(void *ptr) +{ + uk_free(uk_alloc_get_default(), ptr); +} diff --git a/include/arch/cc.h b/include/arch/cc.h new file mode 100644 index 0000000..099c4ac --- /dev/null +++ b/include/arch/cc.h @@ -0,0 +1,89 @@ +/* + * lwip/arch/cc.h + * + * Compiler-specific types and macros for lwIP running on mini-os + * + * Tim Deegan , July 2007 + * Simon Kuenzer , October 2014 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __LWIP_ARCH_CC_H__ +#define __LWIP_ARCH_CC_H__ + +#include +#include +#include +#include +#include +#include +#include + +#define S16_F __PRIs16 +#define U16_F __PRIu16 +#define X16_F __PRIx16 +#define S32_F __PRIs32 +#define U32_F __PRIu32 +#define X32_F __PRIx32 +#define SZT_F __PRIsz + +#define BUG() UK_BUG() + +/* 32 bit checksum calculation */ +#define LWIP_CHKSUM_ALGORITHM 3 +#define ETH_PAD_SIZE 2 + +/* rand */ +#define LWIP_RAND() uk_swrand_randr() + +/* compiler hints for packing lwip's structures */ +#define PACK_STRUCT_FIELD(_x) _x +#define PACK_STRUCT_STRUCT __attribute__ ((packed)) +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_END + +/* platform specific diagnostic output */ +#define LWIP_PLATFORM_DIAG(_x) \ + do { \ + if (DLVL_INFO <= DLVL_MAX) { \ + _lwip_platform_diag _x; \ + } \ + } while(0) + +static inline void _lwip_platform_diag(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + uk_vprintd(DLVL_INFO, fmt, ap); + va_end(ap); +} + +#define LWIP_PLATFORM_ASSERT(_x) UK_ASSERT((_x)) + +/* lightweight synchronization mechanisms */ +#define SYS_ARCH_DECL_PROTECT(_x) unsigned long (_x) +#define SYS_ARCH_PROTECT(_x) do { (_x) = ukplat_lcpu_save_irqf(); } while(0) +#define SYS_ARCH_UNPROTECT(_x) ukplat_lcpu_restore_irqf((_x)) + +#endif /* __LWIP_ARCH_CC_H__ */ diff --git a/include/arch/sys_arch.h b/include/arch/sys_arch.h new file mode 100644 index 0000000..7efec56 --- /dev/null +++ b/include/arch/sys_arch.h @@ -0,0 +1,47 @@ +/* + * lwip/arch/sys_arch.h + * + * Arch-specific semaphores and mailboxes for lwIP running on mini-os + * + * Tim Deegan , July 2007 + * Simon Kuenzer , October 2014 + */ + +#ifndef __LWIP_ARCH_SYS_ARCH_H__ +#define __LWIP_ARCH_SYS_ARCH_H__ + +#include +#include +#include +#include +#if LIBUKSCHED +#include +#endif + +#define SYS_SEM_NULL NULL +#define SYS_MUTEX_NULL NULL +#define SYS_MBOX_NULL NULL + +typedef struct { + struct uk_mutex_mt mtx; + int valid; +} sys_mutex_t; + +typedef struct { + struct uk_semaphore_mt sem; + int valid; +} sys_sem_t; + +typedef struct { + struct uk_alloc *a; + struct uk_mbox_mt *mbox; + int valid; +} sys_mbox_t; + +#if LIBUKSCHED +typedef struct uk_thread *sys_thread_t; +#endif + +typedef unsigned long sys_prot_t; + +#endif /*__LWIP_ARCH_SYS_ARCH_H__ */ diff --git a/include/lwipopts.h b/include/lwipopts.h new file mode 100644 index 0000000..f5d380d --- /dev/null +++ b/include/lwipopts.h @@ -0,0 +1,251 @@ +/* + * lwipopts.h + * + * Configuration for lwIP running on mini-os + * + * Tim Deegan , July 2007 + * Simon Kuenzer , October 2013 + */ +#ifndef __LWIP_LWIPOPTS_H__ +#define __LWIP_LWIPOPTS_H__ + +#include +#include + +#define LWIP_SOCKET 1 +#define LWIP_IPV6 1 +#define SO_REUSE 1 + +/* + * General options/System settings + */ +/* lightweight protection */ +#define SYS_LIGHTWEIGHT_PROT 1 + +/* provide malloc/free by Unikraft */ +#if LWIP_HEAP /* default */ + /* Only use malloc/free for lwIP. + * Every allocation is done by the heap. + * Note: This setting results in the smallest binary + * size but leads to heavy malloc/free usage during + * network processing. + */ + #define MEM_LIBC_MALLOC 1 /* enable heap */ + #define MEMP_MEM_MALLOC 1 /* pool allocations via malloc (thus not from pool in data segment) */ +#elif LWIP_POOLS + /* This is the default configuration (mixed). + * Pools are used for pool allocations and the heap + * is used for all the rest of allocations. + * Note: Per design, lwIP allocates outgoing packet buffers + * from heap (via PBUF_RAM) and incoming from pools (via PBUF_POOL) + * CONFIG_LWIP_PBUF_POOL_SIZE defines the pool size for PBUF_POOL + * allocations + * Note: lwIP allocate pools on the data segment + */ + #define MEM_LIBC_MALLOC 1 /* enable heap */ + #define MEMP_MEM_MALLOC 0 /* pool allocations still via pool */ +#else + #error Configuration error! +#endif /* CONFIG_LWIP_HEAP_ONLY / CONFIG_LWIP_POOLS_ONLY */ + +#define MEMP_SEPARATE_POOLS 1 /* for each pool use a separate array in data segment */ + +//#ifdef CONFIG_LWIP_POOLS_ON_HEAP /* not supported yet */ +//#define MEMP_POOLS_ON_HEAP 1 /* allocate pools on system's heap */ +//#endif + +#define MEM_ALIGNMENT 4 + +#if MEM_LIBC_MALLOC +#include /* size_t */ +void *sys_malloc(size_t size); +void *sys_calloc(int num, size_t size); +void sys_free(void *ptr); + +#define mem_clib_malloc sys_malloc +#define mem_clib_calloc sys_calloc +#define mem_clib_free sys_free +#endif /* MEM_LIBC_MALLOC */ + +#if MEM_USE_POOLS +/* requires lwippools.h */ +#define MEMP_USE_CUSTOM_POOLS 0 +#endif /* MEM_USE_POOLS */ + +/* + * Most features are selected by uk/config.h + */ +#define LWIP_NETIF_REMOVE_CALLBACK 1 +#define LWIP_TIMEVAL_PRIVATE 0 + +/* disable BSD-style socket - layer is provided by libc */ +#define LWIP_COMPAT_SOCKETS 0 + +/* + * Thread options + */ +#ifndef CONFIG_LWIP_NOTHREADS +#define TCPIP_THREAD_NAME "lwip" +#define TCPIP_MBOX_SIZE 256 +#define MEMP_NUM_TCPIP_MSG_INPKT 256 +#endif /* CONFIG_LWIP_NOTHREADS */ + +/* + * ARP options + */ +#define MEMP_NUM_ARP_QUEUE 256 +#define ETHARP_SUPPORT_STATIC_ENTRIES 1 + +/* + * UDP options + */ +//#define MEMP_NUM_UDP_PCB 16 + +/* + * TCP options + */ +#define TCP_MSS LWIP_TCP_MSS + + +#define TCP_CALCULATE_EFF_SEND_MSS 1 +#define IP_FRAG 0 + + + +#if LWIP_WND_SCALE +/* + * Maximum window and scaling factor + * Optimal settings for RX performance are: + * TCP_WND 262143 + * TCP_RCV_SCALE 5 + */ +#if defined CONFIG_LWIP_WND_SCALE_FACTOR && CONFIG_LWIP_WND_SCALE_FACTOR >= 1 +#define TCP_RCV_SCALE CONFIG_LWIP_WND_SCALE_FACTOR /* scaling factor 0..14 */ +#else +#define TCP_RCV_SCALE 4 +#endif /* defined CONFIG_LWIP_WND_SCALE_FACTOR && CONFIG_LWIP_WND_SCALE_FACTOR >= 1 */ +#define TCP_WND 262142 +#define TCP_SND_BUF ( 1024 * 1024 ) + +#else /* LWIP_WND_SCALE */ +/* + * Options when no window scaling is enabled + */ +#define TCP_WND 32766 /* Ideally, TCP_WND should be link bandwidth multiplied by rtt */ +#define TCP_SND_BUF (TCP_WND + (2 * TCP_MSS)) +#endif /* LWIP_WND_SCALE */ + +#define TCP_SNDLOWAT (4 * TCP_MSS) +#define TCP_SND_QUEUELEN (2 * (TCP_SND_BUF) / (TCP_MSS)) +#define TCP_QUEUE_OOSEQ 4 +#define MEMP_NUM_TCP_SEG (MEMP_NUM_TCP_PCB * ((TCP_SND_QUEUELEN) / 5)) +#define MEMP_NUM_FRAG_PBUF 32 + +#define MEMP_NUM_TCP_PCB CONFIG_LWIP_NUM_TCPCON /* max num of sim. TCP connections */ +#define MEMP_NUM_TCP_PCB_LISTEN 32 /* max num of sim. TCP listeners */ + +/* + * DNS options + */ +#define DNS_MAX_SERVERS LWIP_DNS_MAX_SERVERS +#define DNS_TABLE_SIZE LWIP_DNS_TABLE_SIZE +#define DNS_LOCAL_HOST_LIST 1 +#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 1 + +/* + * Pool options + */ +/* PBUF pools */ +#ifndef PBUF_POOL_SIZE +#define PBUF_POOL_SIZE ((TCP_WND + TCP_MSS - 1) / TCP_MSS) +#endif +#ifndef CONFIG_NETFRONT_PERSISTENT_GRANTS +#define LWIP_SUPPORT_CUSTOM_PBUF 1 +#endif +#ifndef MEMP_NUM_PBUF +#define MEMP_NUM_PBUF ((MEMP_NUM_TCP_PCB * (TCP_SND_QUEUELEN)) / 2) +#endif + +/* + * Checksum options + */ +#define CHECKSUM_GEN_IP LWIP_TXCHECKSUM +#define CHECKSUM_GEN_IP6 LWIP_TXCHECKSUM +#define CHECKSUM_GEN_ICMP LWIP_TXCHECKSUM +#define CHECKSUM_GEN_ICMP6 LWIP_TXCHECKSUM +#define CHECKSUM_GEN_UDP LWIP_TXCHECKSUM +#define CHECKSUM_GEN_TCP LWIP_TXCHECKSUM +#define LWIP_CHECKSUM_ON_COPY 1 + +/* Checksum checking is offloaded to the host (lwip-net is a virtual interface) + * TODO: better solution is when netfront forwards checksum flags to lwIP */ +#define CHECKSUM_CHECK_IP LWIP_RXCHECKSUM +#define CHECKSUM_CHECK_UDP LWIP_RXCHECKSUM +#define CHECKSUM_CHECK_TCP LWIP_RXCHECKSUM +#define CHECKSUM_CHECK_ICMP LWIP_RXCHECKSUM +#define CHECKSUM_CHECK_ICMP6 LWIP_RXCHECKSUM +#define CHECKSUM_CHECK_TCP LWIP_RXCHECKSUM + +#ifdef LWIP_MAINLOOP_DEBUG +#define IP_DEBUG LWIP_DBG_ON +#define TCPIP_DEBUG LWIP_DBG_ON +#define TIMERS_DEBUG LWIP_DBG_ON +#endif /* LWIP_MAINLOOP_DEBUG */ + +#ifdef LWIP_IF_DEBUG +#define NETIF_DEBUG LWIP_DBG_ON +#endif /* LWIP_IF_DEBUG */ + +#ifdef LWIP_IP_DEBUG +#define IP_DEBUG LWIP_DBG_ON +#define IP6_DEBUG LWIP_DBG_ON +#define IP_REASS_DEBUG LWIP_DBG_ON +#endif /* LWIP_IP_DEBUG */ + +#ifdef LWIP_UDP_DEBUG +#define UDP_DEBUG LWIP_DBG_ON +#endif /* LWIP_UDP_DEBUG */ + +#ifdef LWIP_TCP_DEBUG +#define TCP_DEBUG LWIP_DBG_ON +#define TCP_FR_DEBUG LWIP_DBG_ON +#define TCP_RTO_DEBUG LWIP_DBG_ON +#define TCP_CWND_DEBUG LWIP_DBG_ON +#define TCP_WND_DEBUG LWIP_DBG_ON +#define TCP_RST_DEBUG LWIP_DBG_ON +#define TCP_QLEN_DEBUG LWIP_DBG_ON +//#define TCP_OUTPUT_DEBUG LWIP_DBG_ON +//#define TCP_INPUT_DEBUG LWIP_DBG_ON +#if LWIP_CHECKSUM_ON_COPY +#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 1 +#endif +#endif /* LWIP_TCP_DEBUG */ + +#ifdef LWIP_SYS_DEBUG +#define SYS_DEBUG LWIP_DBG_ON +#define PBUF_DEBUG LWIP_DBG_ON +#define MEM_DEBUG LWIP_DBG_ON +#define MEMP_DEBUG LWIP_DBG_ON +#endif /* LWIP_SYS_DEBUG */ + +#ifdef LWIP_API_DEBUG +#define SOCKETS_DEBUG LWIP_DBG_ON +#define RAW_DEBUG LWIP_DBG_ON +#define API_MSG_DEBUG LWIP_DBG_ON +#define API_LIB_DEBUG LWIP_DBG_ON +#endif /* LWIP_API_DEBUG */ + +#ifdef LWIP_SERVICE_DEBUG +#define ETHARP_DEBUG LWIP_DBG_ON +#define DNS_DEBUG LWIP_DBG_ON +#define AUTOIP_DEBUG LWIP_DBG_ON +#define DHCP_DEBUG LWIP_DBG_ON +#define ICMP_DEBUG LWIP_DBG_ON +#define SNMP_DEBUG LWIP_DBG_ON +#define SNMP_MSG_DEBUG LWIP_DBG_ON +#define SNMP_MIB_DEBUG LWIP_DBG_ON +#define PPP_DEBUG LWIP_DBG_ON +#define SLIP_DEBUG LWIP_DBG_ON +#endif /* LWIP_SERVICE_DEBUG */ + +#endif /* __LWIP_LWIPOPTS_H__ */ diff --git a/init.c b/init.c new file mode 100644 index 0000000..603e054 --- /dev/null +++ b/init.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +/* This function is called before the any other sys_arch-function is + * called and is meant to be used to initialize anything that has to + * be up and running for the rest of the functions to work. for + * example to set up a pool of semaphores. */ +void sys_init(void) +{ + return; +} + +/* + * This function initializing the lwip network stack + * + */ +int liblwip_init(void) +{ +#if LIBUKSCHED + tcpip_init(NULL, NULL); +#else + lwip_init(); +#endif /* LIBUKSCHED */ + return 0; +} diff --git a/mailbox.c b/mailbox.c new file mode 100644 index 0000000..5d04058 --- /dev/null +++ b/mailbox.c @@ -0,0 +1,121 @@ +#include +#include +#include + +#include + +/* Creates an empty mailbox. */ +err_t sys_mbox_new(sys_mbox_t *mbox, int size) +{ + if (size <= 0) + size = 32; + + UK_ASSERT(mbox); + mbox->a = uk_alloc_get_default(); + UK_ASSERT(mbox->a); + mbox->mbox = uk_mbox_mt_create(mbox->a, size); + if (!mbox->mbox) + return ERR_MEM; + mbox->valid = 1; + return ERR_OK; +} + +int sys_mbox_valid(sys_mbox_t *mbox) +{ + if (!mbox) + return 0; + return (mbox->valid == 1); +} + +void sys_mbox_set_invalid(sys_mbox_t *mbox) +{ + UK_ASSERT(mbox); + mbox->valid = 0; +} + +/* Deallocates a mailbox. If there are messages still present in the + * mailbox when the mailbox is deallocated, it is an indication of a + * programming error in lwIP and the developer should be notified. */ +void sys_mbox_free(sys_mbox_t *mbox) +{ + UK_ASSERT(sys_mbox_valid(mbox)); + + uk_mbox_mt_free(mbox->a, mbox->mbox); + sys_mbox_set_invalid(mbox); +} + +/* Posts the "msg" to the mailbox. */ +void sys_mbox_post(sys_mbox_t *mbox, void *msg) +{ + UK_ASSERT(sys_mbox_valid(mbox)); + + if (!msg) { /* FIXME? */ + uk_printd(DLVL_WARN, "Ignore posting NULL message"); + return; + } + + uk_mbox_mt_post(mbox->mbox, msg); +} + +/* Try to post the "msg" to the mailbox. */ +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ + UK_ASSERT(sys_mbox_valid(mbox)); + + if (!msg) { /* FIXME? */ + uk_printd(DLVL_WARN, "Ignore posting NULL message"); + return ERR_OK; + } + + if (uk_mbox_mt_post_try(mbox->mbox, msg) != 0) + return ERR_MEM; + return ERR_OK; +} + +/* Blocks the thread until a message arrives in the mailbox, but does + * not block the thread longer than "timeout" milliseconds (similar to + * the sys_arch_sem_wait() function). The "msg" argument is a result + * parameter that is set by the function (i.e., by doing "*msg = + * ptr"). The "msg" parameter maybe NULL to indicate that the message + * should be dropped. + * + * The return values are the same as for the sys_arch_sem_wait() function: + * Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + * timeout. */ +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) +{ + __nsec nsret; + + UK_ASSERT(sys_mbox_valid(mbox)); + + nsret = uk_mbox_mt_recv_to(mbox->mbox, msg, + ukarch_time_msec_to_nsec((__nsec) timeout)); + if (unlikely(nsret == __NSEC_MAX)) + return SYS_ARCH_TIMEOUT; + return (u32_t) ukarch_time_nsec_to_msec(nsret); +} + +/* This is similar to sys_arch_mbox_fetch, however if a message is not + * present in the mailbox, it immediately returns with the code + * SYS_MBOX_EMPTY. On success 0 is returned. + * + * To allow for efficient implementations, this can be defined as a + * function-like macro in sys_arch.h instead of a normal function. For + * example, a naive implementation could be: + * #define sys_arch_mbox_tryfetch(mbox,msg) \ + * sys_arch_mbox_fetch(mbox,msg,1) + * although this would introduce unnecessary delays. */ + +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { + void *rmsg; + + UK_ASSERT(sys_mbox_valid(mbox)); + + rmsg = uk_mbox_mt_recv_try(mbox->mbox); + if (!rmsg) + return SYS_MBOX_EMPTY; + + if (msg) + *msg = rmsg; + return 0; +} diff --git a/mutex.c b/mutex.c new file mode 100644 index 0000000..ecd20ec --- /dev/null +++ b/mutex.c @@ -0,0 +1,40 @@ +#include +#include +#include + +#include + +/* Initializes a new semaphore. The "count" argument specifies + * the initial state of the semaphore. */ +err_t sys_mutex_new(sys_mutex_t *mtx) +{ + uk_mutex_mt_init(&mtx->mtx); + mtx->valid = 1; + return ERR_OK; +} + +int sys_mutex_valid(sys_mutex_t *mtx) +{ + return (mtx->valid == 1); +} + +void sys_mutex_set_invalid(sys_mutex_t *mtx) +{ + mtx->valid = 0; +} + +void sys_mutex_free(sys_mutex_t *mtx) +{ + sys_mutex_set_invalid(mtx); +} + +/* Signals a mtxaphore. */ +void sys_mutex_lock(sys_mutex_t *mtx) +{ + uk_mutex_mt_hold(&mtx->mtx); +} + +void sys_mutex_unlock(sys_mutex_t *mtx) +{ + uk_mutex_mt_release(&mtx->mtx); +} diff --git a/patches/0001-timeval-for-socket-c.patch b/patches/0001-timeval-for-socket-c.patch new file mode 100644 index 0000000..07ded91 --- /dev/null +++ b/patches/0001-timeval-for-socket-c.patch @@ -0,0 +1,11 @@ +--- src/api/sockets.c 2018-03-05 16:12:39.917974880 +0100 ++++ src/api/sockets.c 2018-03-05 16:12:24.577997842 +0100 +@@ -44,6 +44,8 @@ + * + */ + ++#include ++ + #include "lwip/opt.h" + + #if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ diff --git a/semaphore.c b/semaphore.c new file mode 100644 index 0000000..2f728d7 --- /dev/null +++ b/semaphore.c @@ -0,0 +1,56 @@ +#include +#include +#include + +#include + +/* Initializes a new semaphore. The "count" argument specifies + * the initial state of the semaphore. */ +err_t sys_sem_new(sys_sem_t *sem, u8_t count) +{ + uk_semaphore_mt_init(&sem->sem, (long) count); + sem->valid = 1; + return ERR_OK; +} + +int sys_sem_valid(sys_sem_t *sem) +{ + return (sem->valid == 1); +} + +void sys_sem_set_invalid(sys_sem_t *sem) +{ + sem->valid = 0; +} + +void sys_sem_free(sys_sem_t *sem) +{ + sys_sem_set_invalid(sem); +} + +/* Signals a semaphore. */ +void sys_sem_signal(sys_sem_t *sem) +{ + uk_semaphore_mt_up(&sem->sem); +} + +/* Blocks the thread while waiting for the semaphore to be + * signaled. If the "timeout" argument is non-zero, the thread should + * only be blocked for the specified time (measured in + * milliseconds). + * + * If the timeout argument is non-zero, the return value is the number of + * milliseconds spent waiting for the semaphore to be signaled. If the + * semaphore wasn't signaled within the specified time, the return value is + * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + * (i.e., it was already signaled), the function may return zero. */ +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) +{ + __nsec nsret; + + nsret = uk_semaphore_mt_down_to(&sem->sem, + ukarch_time_msec_to_nsec((__nsec) timeout)); + if (unlikely(nsret == __NSEC_MAX)) + return SYS_ARCH_TIMEOUT; + return (u32_t) ukarch_time_nsec_to_msec(nsret); +} diff --git a/threads.c b/threads.c new file mode 100644 index 0000000..79d06fa --- /dev/null +++ b/threads.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include +#include + +/* Starts a new thread with priority "prio" that will begin its execution in the + * function "thread()". The "arg" argument will be passed as an argument to the + * thread() function. The id of the new thread is returned. Both the id and + * the priority are system dependent. */ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio) +{ + static struct thread *t; + if (stacksize > __STACK_SIZE) { + uk_printd("Can't create lwIP thread: stack size %u is too large (> %u)\n", stacksize, __STACK_SIZE); + UK_CRASH("Dying\n"); + } + t = uk_thread_create((char *) name, NULL, thread, arg); + return t; +} diff --git a/time.c b/time.c new file mode 100644 index 0000000..ca6be8f --- /dev/null +++ b/time.c @@ -0,0 +1,8 @@ +#include +#include +#include + +u32_t sys_now(void) +{ + return (u32_t) ukarch_time_nsec_to_msec(ukplat_monotonic_clock()); +} -- 2.39.5