--- /dev/null
+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
--- /dev/null
+# liblwip: Makefile.uk
+#
+# Authors: Felipe Huici <felipe.huici@neclab.eu>
+# Simon Kuenzer <simon.kuenzer@neclab.eu>
+#
+#
+# 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
--- /dev/null
+#include <uk/alloc.h>
+
+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);
+}
--- /dev/null
+/*
+ * lwip/arch/cc.h
+ *
+ * Compiler-specific types and macros for lwIP running on mini-os
+ *
+ * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007
+ * Simon Kuenzer <Simon.Kuenzer@neclab.eu>, 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 <uk/arch/types.h>
+#include <uk/plat/lcpu.h>
+#include <uk/print.h>
+#include <uk/assert.h>
+#include <uk/swrand.h>
+#include <errno.h>
+#include <stdarg.h>
+
+#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__ */
--- /dev/null
+/*
+ * lwip/arch/sys_arch.h
+ *
+ * Arch-specific semaphores and mailboxes for lwIP running on mini-os
+ *
+ * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007
+ * Simon Kuenzer <Simon.Kuenzer@neclab.eu>, October 2014
+ */
+
+#ifndef __LWIP_ARCH_SYS_ARCH_H__
+#define __LWIP_ARCH_SYS_ARCH_H__
+
+#include <stdlib.h>
+#include <uk/mutex.h>
+#include <uk/semaphore.h>
+#include <uk/mbox.h>
+#if LIBUKSCHED
+#include <uk/thread.h>
+#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__ */
--- /dev/null
+/*
+ * lwipopts.h
+ *
+ * Configuration for lwIP running on mini-os
+ *
+ * Tim Deegan <Tim.Deegan@eu.citrix.net>, July 2007
+ * Simon Kuenzer <simon.kuenzer@neclab.eu>, October 2013
+ */
+#ifndef __LWIP_LWIPOPTS_H__
+#define __LWIP_LWIPOPTS_H__
+
+#include <inttypes.h>
+#include <uk/config.h>
+
+#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 <stddef.h> /* 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__ */
--- /dev/null
+#include <uk/config.h>
+#include <lwip/tcpip.h>
+#include <lwip/init.h>
+#include <uk/plat/ctors.h>
+
+/* 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;
+}
--- /dev/null
+#include <uk/mbox.h>
+#include <uk/arch/time.h>
+#include <lwip/sys.h>
+
+#include <uk/essentials.h>
+
+/* 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;
+}
--- /dev/null
+#include <uk/mutex.h>
+#include <uk/arch/time.h>
+#include <lwip/sys.h>
+
+#include <uk/essentials.h>
+
+/* 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);
+}
--- /dev/null
+--- 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 @@
+ *\r
+ */\r
+ \r
++#include <sys/time.h>\r
++\r
+ #include "lwip/opt.h"\r
+ \r
+ #if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */\r
--- /dev/null
+#include <uk/semaphore.h>
+#include <uk/arch/time.h>
+#include <lwip/sys.h>
+
+#include <uk/essentials.h>
+
+/* 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);
+}
--- /dev/null
+#include <uk/arch/limits.h>
+#include <uk/sched.h>
+#include <uk/thread.h>
+#include <uk/print.h>
+#include <uk/assert.h>
+#include <lwip/sys.h>
+
+/* 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;
+}
--- /dev/null
+#include <uk/arch/time.h>
+#include <uk/plat/time.h>
+#include <lwip/sys.h>
+
+u32_t sys_now(void)
+{
+ return (u32_t) ukarch_time_nsec_to_msec(ukplat_monotonic_clock());
+}