Remove legacy lwIP plugins

Now that the lwIP VFS plugin has become a first class IP stack it is
time to remove the lwIP 1.x library and the associated libc plugins.

Fix #2958
This commit is contained in:
Emery Hemingway 2018-08-31 11:03:13 +02:00 committed by Norman Feske
parent 1370fa7631
commit fcbe060096
44 changed files with 43 additions and 3039 deletions

View File

@ -13,6 +13,7 @@ set build_components {
drivers/timer drivers/usb drivers/timer drivers/usb
server/tcp_terminal server/tcp_terminal
test/terminal_echo test/terminal_echo
lib/vfs/lwip
} }
proc gpio_drv { } { if {[have_spec rpi] && [have_spec hw]} { return hw_gpio_drv } proc gpio_drv { } { if {[have_spec rpi] && [have_spec hw]} { return hw_gpio_drv }
@ -66,8 +67,11 @@ set config {
<provides> <service name="Terminal"/> </provides> <provides> <service name="Terminal"/> </provides>
<config> <config>
<policy label_prefix="test-terminal_echo" port="8888"/> <policy label_prefix="test-terminal_echo" port="8888"/>
<vfs> <dir name="dev"> <log/> </dir> </vfs> <vfs>
<libc stdout="/dev/log"/> <dir name="dev"> <log/> </dir>
<dir name="socket"> <lwip dhcp="yes"/> </dir>
</vfs>
<libc stdout="/dev/log" socket="/socket"/>
</config> </config>
<route> <route>
<any-service> <parent/> <any-child/> </any-service> <any-service> <parent/> <any-child/> </any-service>
@ -103,6 +107,7 @@ set boot_modules {
libc.lib.so vfs.lib.so libc_pipe.lib.so lwip_legacy.lib.so pthread.lib.so libc.lib.so vfs.lib.so libc_pipe.lib.so lwip_legacy.lib.so pthread.lib.so
tcp_terminal tcp_terminal
test-terminal_echo test-terminal_echo
vfs_lwip.lib.so
} }
append_platform_drv_boot_modules append_platform_drv_boot_modules

View File

@ -48,7 +48,7 @@ append config {
<provides> <service name="Terminal"/> </provides> <provides> <service name="Terminal"/> </provides>
<config ld_verbose="yes"> <config ld_verbose="yes">
<policy label="test-terminal_echo" port="8888"/> <policy label="test-terminal_echo" port="8888"/>
<libc stdout="/dev/log"> <libc stdout="/dev/log" socket="/socket"/>
<vfs> <vfs>
<dir name="dev"> <log/> </dir> <dir name="dev"> <log/> </dir>
<dir name="socket"> <dir name="socket">

View File

@ -1,203 +0,0 @@
#
# \brief Automated testing of http_blk
# \author Stefan Kalkowski
# \date 2013-11-29
#
if {[have_spec odroid_xu]} {
puts "Run script does not support this platform."
exit 0
}
set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi]]
set use_nic_driver [expr !$use_usb_driver && ![have_spec imx53]]
if {[expr !$use_usb_driver && !$use_nic_driver]} {
puts "\n Run script is not supported on this platform. \n"; exit 0 }
if {$use_usb_driver} { set network_driver "usb_drv" }
if {$use_nic_driver} { set network_driver "nic_drv" }
set build_components {
core init
drivers/timer
server/nic_bridge
server/http_blk
app/lighttpd
test/rom_blk
}
# platform-specific modules
lappend_if $use_usb_driver build_components drivers/usb
lappend_if $use_nic_driver build_components drivers/nic
lappend_if [have_spec gpio] build_components drivers/gpio
source ${genode_dir}/repos/base/run/platform_drv.inc
append_platform_drv_build_components
build $build_components
create_boot_directory
proc gpio_drv { } { if {[have_spec rpi] && [have_spec hw]} { return hw_gpio_drv }
if {[have_spec rpi] && [have_spec foc]} { return foc_gpio_drv }
return gpio_drv }
append config {
<config>
<parent-provides>
<service name="ROM"/>
<service name="LOG"/>
<service name="RM"/>
<service name="CPU"/>
<service name="PD"/>
<service name="IRQ"/>
<service name="IO_PORT"/>
<service name="IO_MEM"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
</start>}
append_if [have_spec gpio] config "
<start name=\"[gpio_drv]\">
<resource name=\"RAM\" quantum=\"4M\"/>
<provides><service name=\"Gpio\"/></provides>
<config/>
</start>"
append_if $use_usb_driver config {
<start name="usb_drv" caps="120">
<resource name="RAM" quantum="12M"/>
<provides>
<service name="Nic"/>
</provides>
<config ehci="yes">
<nic mac="02:00:00:00:01:01"/>
</config>
</start>}
append_if $use_nic_driver config {
<start name="nic_drv">
<binary name="} [nic_drv_binary] {"/>
<resource name="RAM" quantum="4M"/>
<provides><service name="Nic"/></provides>
</start>}
append_platform_drv_config
append config {
<start name="nic_bridge">
<resource name="RAM" quantum="4M"/>
<provides><service name="Nic"/></provides>
<config>
<policy label_prefix="lighttpd" ip_addr="10.0.1.1"/>
<policy label_prefix="http_blk" ip_addr="10.0.1.2"/>
</config>
<route>
<service name="Nic">}
append config " <child name=\"$network_driver\"/>"
append config {
</service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="http_blk">
<resource name="RAM" quantum="2M" />
<provides><service name="Block"/></provides>
<config block_size="512" uri="http://10.0.1.1/index.bin">
<libc ip_addr="10.0.1.2" gateway="10.0.1.5" netmask="255.255.255.0"/>
</config>
<route>
<service name="Nic"> <child name="nic_bridge"/> </service>
<service name="ROM"> <parent/> </service>
<any-service> <any-child /> <parent/> </any-service>
</route>
</start>
<start name="test-rom_blk">
<resource name="RAM" quantum="3M"/>
<config file="index.bin"/>
</start>
<start name="lighttpd">
<resource name="RAM" quantum="1G" />
<config>
<arg value="lighttpd" />
<arg value="-f" />
<arg value="/etc/lighttpd/lighttpd.conf" />
<arg value="-D" />
<vfs>
<dir name="dev">
<log/>
<null/>
</dir>
<dir name="etc">
<dir name="lighttpd">
<inline name="lighttpd.conf">
# lighttpd configuration
server.port = 80
server.document-root = "/website"
server.event-handler = "select"
server.network-backend = "write"
index-file.names = (
"index.xhtml", "index.html", "index.htm"
)
mimetype.assign = (
".html" => "text/html",
".htm" => "text/html"
)
</inline>
</dir>
</dir>
<dir name="website">
<rom name="index.bin" as="index.bin" />
</dir>
</vfs>
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"
ip_addr="10.0.1.1" gateway="10.0.1.5"
netmask="255.255.255.0"/>
</config>
<route>
<service name="Nic"> <child name="nic_bridge"/> </service>
<service name="ROM"> <parent/> </service>
<any-service> <any-child /> <parent/> </any-service>
</route>
</start>
</config>}
install_config $config
catch { exec dd if=/dev/zero of=bin/index.bin bs=512 count=400 }
#
# Boot modules
#
# generic modules
set boot_modules {
core ld.lib.so init timer
libc.lib.so vfs.lib.so libm.lib.so posix.lib.so
lwip_legacy.lib.so zlib.lib.so
lighttpd nic_bridge http_blk index.bin test-rom_blk
}
# platform-specific modules
lappend_if [have_spec gpio] boot_modules [gpio_drv]
lappend_if $use_usb_driver boot_modules usb_drv
lappend_if $use_nic_driver boot_modules [nic_drv_binary]
append_platform_drv_boot_modules
build_boot_image $boot_modules
append_if [have_spec x86] qemu_args " -net nic,model=e1000 "
append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118 "
append qemu_args " -net user -redir tcp:5555::80 "
append qemu_args " -nographic -serial mon:stdio "
run_genode_until {.*all done, finished!.*} 120
exec rm -f bin/index.bin

View File

@ -20,6 +20,7 @@ set build_components {
drivers/timer drivers/nic drivers/timer drivers/nic
server/tcp_terminal server/tcp_terminal
test/terminal_echo test/terminal_echo
lib/vfs/lwip
} }
source ${genode_dir}/repos/base/run/platform_drv.inc source ${genode_dir}/repos/base/run/platform_drv.inc
@ -58,12 +59,15 @@ set config {
<provides> <service name="Nic"/> </provides> <provides> <service name="Nic"/> </provides>
</start> </start>
<start name="tcp_terminal" caps="200"> <start name="tcp_terminal" caps="200">
<resource name="RAM" quantum="2560K"/> <resource name="RAM" quantum="8M"/>
<provides> <service name="Terminal"/> </provides> <provides> <service name="Terminal"/> </provides>
<config> <config>
<policy label_prefix="test-terminal_echo" port="8888"/> <policy label_prefix="test-terminal_echo" port="8888"/>
<vfs> <dir name="dev"> <log/> </dir> </vfs> <vfs>
<libc stdout="/dev/log"/> <dir name="dev"> <log/> </dir>
<dir name="socket"> <lwip dhcp="yes"/> </dir>
</vfs>
<libc stdout="/dev/log" socket="/socket"/>
</config> </config>
</start> </start>
<start name="test-terminal_echo"> <start name="test-terminal_echo">
@ -89,6 +93,7 @@ set boot_modules {
libc.lib.so vfs.lib.so pthread.lib.so lwip_legacy.lib.so libc_pipe.lib.so libc.lib.so vfs.lib.so pthread.lib.so lwip_legacy.lib.so libc_pipe.lib.so
tcp_terminal tcp_terminal
test-terminal_echo test-terminal_echo
vfs_lwip.lib.so
} }
# platform-specific modules # platform-specific modules

View File

@ -14,8 +14,6 @@
#include <base/child.h> #include <base/child.h>
#include <base/log.h> #include <base/log.h>
#include <base/sleep.h> #include <base/sleep.h>
#include <lwip_legacy/genode.h>
#include <nic/packet_allocator.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>

View File

@ -1,6 +1,5 @@
TARGET = http_blk TARGET = http_blk
SRC_CC = main.cc http.cc SRC_CC = main.cc http.cc
LIBS = libc libc_lwip_nic_dhcp LIBS = libc
CC_CXX_WARN_STRICT = CC_CXX_WARN_STRICT =

View File

@ -1,5 +1,5 @@
TARGET = tcp_terminal TARGET = tcp_terminal
SRC_CC = main.cc SRC_CC = main.cc
LIBS = libc pthread libc_lwip_nic_dhcp libc_pipe LIBS = libc pthread libc_pipe
CC_CXX_WARN_STRICT = CC_CXX_WARN_STRICT =

View File

@ -1,65 +0,0 @@
/*
* \brief Some size definitions and macros needed by LwIP.
* \author Stefan Kalkowski
* \date 2009-11-10
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef __LWIP__ARCH__CC_H__
#define __LWIP__ARCH__CC_H__
#include <stddef.h>
#include <base/fixed_stdint.h>
typedef genode_uint8_t u8_t;
typedef genode_int8_t s8_t;
typedef genode_uint16_t u16_t;
typedef genode_int16_t s16_t;
typedef genode_uint32_t u32_t;
typedef genode_int32_t s32_t;
typedef unsigned long mem_ptr_t;
/* Define (sn)printf formatters */
#define U16_F "u" // we don't have hu
#define S16_F "d" // we don't have hd
#define X16_F "x" // we don't have hx
#define U32_F "u"
#define S32_F "d"
#define X32_F "x"
void lwip_printf(const char *format, ...);
void lwip_sleep_forever(void);
#define LWIP_PLATFORM_DIAG(x) do { lwip_printf x; } while(0)
#ifdef GENODE_RELEASE
#define LWIP_PLATFORM_ASSERT(x)
#else /* GENODE_RELEASE */
#define LWIP_PLATFORM_ASSERT(x) \
do { \
lwip_printf("Assertion \"%s\" failed at %s:%u\n", \
x, __FILE__, __LINE__); \
lwip_sleep_forever(); \
} while (0)
#endif /* GENODE_RELEASE */
#define PACK_STRUCT_FIELD(x) x
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_END
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif /* BYTE_ORDER */
#define mem_realloc realloc
#endif /* __LWIP__ARCH__CC_H__ */

View File

@ -1,20 +0,0 @@
/*
* \brief Header file with macros needed by LwIP.
* \author Stefan Kalkowski
* \date 2009-11-10
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef __LWIP__ARCH__PERF_H__
#define __LWIP__ARCH__PERF_H__
#define PERF_START
#define PERF_STOP(x)
#endif /* __LWIP__ARCH__PERF_H__ */

View File

@ -1,38 +0,0 @@
/*
* \brief Platform definitions for certain types in LwIP.
* \author Stefan Kalkowski
* \date 2009-11-10
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef __LWIP__ARCH__SYS_ARCH_H__
#define __LWIP__ARCH__SYS_ARCH_H__
#include <arch/cc.h>
struct _sys_sem_t {
void* ptr;
};
typedef struct _sys_sem_t sys_sem_t;
struct _sys_mbox_t {
void* ptr;
};
typedef struct _sys_mbox_t sys_mbox_t;
typedef mem_ptr_t sys_thread_t;
typedef mem_ptr_t sys_prot_t;
#define SYS_MBOX_NULL 0
#define SYS_SEM_NULL 0
sys_prot_t sys_arch_protect(void);
void sys_arch_unprotect(sys_prot_t pval);
#endif /* __LWIP__ARCH__SYS_ARCH_H__ */

View File

@ -1,61 +0,0 @@
/*
* \brief Genode-specific lwIP API
* \author Christian Helmuth
* \author Stefan Kalkowski
* \date 2010-02-22
*
* This header is included from C sources.
*/
/*
* Copyright (C) 2010-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef __LWIP__GENODE_H__
#define __LWIP__GENODE_H__
#include <base/fixed_stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Initialize the TCP/IP stack */
void lwip_tcpip_init(void);
/**
* Initialize lwIP for NIC session
*
* \param ip_addr IPv4 address in network byte order, or zero when requesting
* DHCP
* \param netmask IPv4 network mask in network byte order
* \param gateway IPv4 network-gateway address in network byte order
* \param tx_buf_size packet stream buffer size for TX direction
* \param rx_buf_size packet stream buffer size for RX direction
*
* \return 0 on success, or 1 if DHCP failed.
*
* This function initializes Genode's nic_drv and does optionally send DHCP
* requests.
*/
int lwip_nic_init(genode_int32_t ip_addr,
genode_int32_t netmask,
genode_int32_t gateway,
unsigned long tx_buf_size,
unsigned long rx_buf_size);
/**
* Pass on link-state changes to lwIP
*
* \param state current link-state
*/
void lwip_nic_link_state_changed(int state);
#ifdef __cplusplus
}
#endif
#endif /* __LWIP__GENODE_H__ */

View File

@ -1,141 +0,0 @@
/*
* \brief Configuration file for LwIP, adapt it to your needs.
* \author Stefan Kalkowski
* \date 2009-11-10
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef __LWIP__LWIPOPTS_H__
#define __LWIP__LWIPOPTS_H__
#include <stdlib.h>
#include <string.h>
#define NO_SYS 0 /* single-threaded? do not touch! */
#define SYS_LIGHTWEIGHT_PROT 1 /* do we provide lightweight protection */
#define LWIP_ARP 1 /* ARP support */
#define LWIP_RAW 0 /* LwIP raw API */
#define LWIP_UDP 1 /* UDP support */
#define LWIP_TCP 1 /* TCP support */
#define LWIP_ICMP 1 /* ICMP support */
#define LWIP_DNS 1 /* DNS support */
#define LWIP_DHCP 1 /* DHCP support */
#define LWIP_SOCKET 1 /* LwIP socket API */
#define LWIP_COMPAT_SOCKETS 0 /* Libc compatibility layer */
#define LWIP_COMPAT_MUTEX 1 /* use binary semaphore instead of mutex */
#define LWIP_NETIF_API 1 /* Network interface API */
#define LWIP_NETIF_LOOPBACK 1 /* Looping back to same address? */
#define LWIP_HAVE_LOOPIF 1 /* 127.0.0.1 support ? */
#define LWIP_STATS 0 /* disable stating */
#define LWIP_STATS_DISPLAY 0 /* disable stating display function */
#define LWIP_SO_RCVTIMEO 1 /* support timeouts for socket recv */
#define LWIP_SO_SNDTIMEO 1 /* support timeouts for socket send */
#define LWIP_TCP_TIMESTAMPS 1
#define LWIP_SO_RCVBUF 1 /* enable SO_RCVBUF */
#define SO_REUSE 1 /* enable SO_REUSE */
#define LWIP_WND_SCALE 1 /* enable window scaling */
#define TCP_RCV_SCALE 2 /* receive scale factor IETF RFC 1323 */
#if LWIP_DHCP
#define LWIP_NETIF_STATUS_CALLBACK 1 /* callback function used for interface changes */
#define LWIP_NETIF_LINK_CALLBACK 1 /* callback function used for link-state changes */
#endif
/***********************************
** Checksum calculation settings **
***********************************/
/* checksum calculation for outgoing packets can be disabled if the hardware supports it */
#define CHECKSUM_GEN_IP 1 /* calculate checksum for outgoing IP packets */
#define CHECKSUM_GEN_TCP 1 /* calculate checksum for outgoing TCP packets */
#define CHECKSUM_CHECK_IP 1 /* check checksum of incoming IP packets */
#define CHECKSUM_CHECK_TCP 1 /* check checksum of incoming TCP packets */
#define LWIP_CHECKSUM_ON_COPY 1 /* calculate checksum during memcpy */
/*********************
** Memory settings **
*********************/
#define MEM_LIBC_MALLOC 1
#define MEMP_MEM_MALLOC 1
/* MEM_ALIGNMENT > 4 e.g. for x86_64 are not supported, see Genode issue #817 */
#define MEM_ALIGNMENT 4
#define DEFAULT_ACCEPTMBOX_SIZE 128
#define TCPIP_MBOX_SIZE 128
#define TCP_MSS 1460
/*
* The TCP window scaling is implemented for servers only, while the client
* implementation just uses the lower 16 bits of the TCP_WND configuration
* value. We, therefore, maximize the TCP_WND value to ~64K.
*/
#define TCP_WND ((96 * TCP_MSS) & 0xffff)
/*
* The window scale option (http://tools.ietf.org/html/rfc1323) patch of lwIP
* definitely works solely for the receive window, not for the send window.
* Setting the send window size to the maximum of an 16bit value, 65535,
* or multiple of it (x * 65536 - 1) results in the same performance.
* Everything else decrease performance.
*/
#define TCP_SND_BUF (65535)
#define TCP_SND_QUEUELEN ((32 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
#define RECV_BUFSIZE_DEFAULT (512*1024)
#define PBUF_POOL_SIZE 96
/*
* We reduce the maximum segment lifetime from one minute to one second to
* avoid queuing up PCBs in TIME-WAIT state. This is the state, PCBs end up
* after closing a TCP connection socket at the server side. The number of PCBs
* in this state is apparently not limited by the value of 'MEMP_NUM_TCP_PCB'.
* One allocation costs around 160 bytes. If clients connect to the server at a
* high rate, those allocations accumulate quickly and thereby may exhaust the
* memory of the server. By reducing the segment lifetime, PCBs in TIME-WAIT
* state are cleaned up from the 'tcp_tw_pcbs' queue in a more timely fashion
* (by 'tcp_slowtmr()').
*/
#define TCP_MSL 1000UL
#define MEMP_NUM_SYS_TIMEOUT 16
#define MEMP_NUM_TCP_PCB 128
#define MEMP_NUM_NETCONN (MEMP_NUM_TCP_PCB + MEMP_NUM_UDP_PCB + MEMP_NUM_RAW_PCB + MEMP_NUM_TCP_PCB_LISTEN - 1)
void genode_memcpy(void * dst, const void *src, unsigned long size);
#define MEMCPY(dst,src,len) genode_memcpy(dst,src,len)
/********************
** Debug settings **
********************/
/* #define LWIP_DEBUG */
/* #define DHCP_DEBUG LWIP_DBG_ON */
/* #define ETHARP_DEBUG LWIP_DBG_ON */
/* #define NETIF_DEBUG LWIP_DBG_ON */
/* #define PBUF_DEBUG LWIP_DBG_ON */
/* #define API_LIB_DEBUG LWIP_DBG_ON */
/* #define API_MSG_DEBUG LWIP_DBG_ON */
/* #define SOCKETS_DEBUG LWIP_DBG_ON */
/* #define ICMP_DEBUG LWIP_DBG_ON */
/* #define INET_DEBUG LWIP_DBG_ON */
/* #define IP_DEBUG LWIP_DBG_ON */
/* #define IP_REASS_DEBUG LWIP_DBG_ON */
/* #define RAW_DEBUG LWIP_DBG_ON */
/* #define MEM_DEBUG LWIP_DBG_ON */
/* #define MEMP_DEBUG LWIP_DBG_ON */
/* #define SYS_DEBUG LWIP_DBG_ON */
/* #define TCP_DEBUG LWIP_DBG_ON */
#endif /* __LWIP__LWIPOPTS_H__ */

View File

@ -1,2 +0,0 @@
INC_DIR += $(call select_from_ports,lwip_legacy)/include/lwip_legacy
INC_DIR += $(call select_from_repositories,include/lwip_legacy)

View File

@ -1,7 +0,0 @@
SRC_CC = init.cc plugin.cc
vpath %.cc $(REP_DIR)/src/lib/libc_lwip
LIBS += lwip_legacy libc
CC_CXX_WARN_STRICT =

View File

@ -1,7 +0,0 @@
SRC_CC = init.cc
vpath %.cc $(REP_DIR)/src/lib/libc_lwip_loopback
LIBS += lwip_legacy libc libc_lwip
CC_CXX_WARN_STRICT =

View File

@ -1,7 +0,0 @@
SRC_CC = plugin.cc
vpath %.cc $(REP_DIR)/src/lib/libc_lwip_nic_dhcp
LIBS += lwip_legacy libc libc_lwip
CC_CXX_WARN_STRICT =

View File

@ -1,51 +0,0 @@
#
# lwIP TCP/IP library
#
# The library implementes TCP and UDP as well as DNS and DHCP.
#
LWIP_PORT_DIR := $(call select_from_ports,lwip_legacy)
LWIP_DIR := $(LWIP_PORT_DIR)/src/lib/lwip_legacy
# Genode platform files
SRC_CC = nic.cc printf.cc sys_arch.cc
# Core files
SRC_C = init.c mem.c memp.c netif.c pbuf.c stats.c udp.c raw.c sys.c \
tcp.c tcp_in.c tcp_out.c dhcp.c dns.c timers.c def.c inet_chksum.c
# IPv4 files
SRC_C += icmp.c igmp.c ip4_addr.c ip4.c ip_frag.c
# API files
SRC_C += err.c api_lib.c api_msg.c netbuf.c netdb.c netifapi.c sockets.c \
tcpip.c
# Network interface files
SRC_C += etharp.c
LIBS = alarm libc timed_semaphore
D_OPTS = ERRNO
D_OPTS := $(addprefix -D,$(D_OPTS))
CC_DEF += $(D_OPTS)
LD_OPT += --version-script=$(REP_DIR)/src/lib/lwip_legacy/symbol.map
INC_DIR += $(REP_DIR)/include/lwip_legacy \
$(LWIP_PORT_DIR)/include/lwip_legacy \
$(LWIP_DIR)/src/include \
$(LWIP_DIR)/src/include/ipv4 \
$(LWIP_DIR)/src/include/api \
$(LWIP_DIR)/src/include/netif \
$(REP_DIR)/src/lib/lwip_legacy/include
vpath %.cc $(REP_DIR)/src/lib/lwip_legacy/platform
vpath %.c $(LWIP_DIR)/src/core
vpath %.c $(LWIP_DIR)/src/core/ipv4
vpath %.c $(LWIP_DIR)/src/api
vpath %.c $(LWIP_DIR)/src/netif
SHARED_LIB = yes
CC_CXX_WARN_STRICT =

View File

@ -1 +0,0 @@
7f5610426ed8c4c64903136122d9ba58836cdc89

View File

@ -1,30 +0,0 @@
LICENSE := BSD
VERSION := git
DOWNLOADS := lwip.git window_scaling_patch.file
URL(lwip) := git://git.savannah.nongnu.org/lwip.git
REV(lwip) := fe63f36656bd66b4051bdfab93e351a584337d7c
DIR(lwip) := src/lib/lwip_legacy
URL(window_scaling_patch) := https://savannah.nongnu.org/patch/download.php?file_id=28026
NAME(window_scaling_patch) := src/lib/lwip_legacy/window_scaling.patch
SHA(window_scaling_patch) := b8dcaa2e0508208222e3e84a42cbe3eba6f6bfc728a5ba62d0d6c4c0c548e46f
PATCHES := $(addprefix src/lib/lwip_legacy/,window_scaling.patch \
errno.patch \
libc_select_notify.patch \
sockets_c_errno.patch \
sol_socket_definition.patch \
remove_warnings.patch \
api_msg.patch \
nonblocking_connect.patch)
PATCH_OPT := -p1 -d src/lib/lwip_legacy
DIRS := include/lwip_legacy/lwip include/lwip_legacy/netif
DIR_CONTENT(include/lwip_legacy/lwip) := src/lib/lwip_legacy/src/include/lwip/*.h \
src/lib/lwip_legacy/src/include/ipv4/lwip/*.h \
src/lib/lwip_legacy/src/include/ipv6/lwip/*.h
DIR_CONTENT(include/lwip_legacy/netif) := src/lib/lwip_legacy/src/include/netif/*.h

View File

@ -1,20 +0,0 @@
/*
* \brief lwip plugin creation
* \author Christian Prochaska
* \date 2010-02-12
*
*/
/*
* Copyright (C) 2010-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
extern void create_lwip_plugin();
void __attribute__((constructor)) init_libc_lwip(void)
{
create_lwip_plugin();
}

View File

@ -1,548 +0,0 @@
/*
* \brief Lwip plugin implementation
* \author Christian Prochaska
* \author Norman Feske
* \date 2010-02-12
*/
/*
* Copyright (C) 2010-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#include <base/env.h>
#include <base/log.h>
#define LWIP_COMPAT_SOCKETS 0
/* rename lwip functions that have the same name in the libc to lwip_*() */
#define addrinfo lwip_addrinfo
#define fd_set lwip_fd_set
#define hostent lwip_hostent
#define linger lwip_linger
#define sockaddr lwip_sockaddr
#define timeval lwip_timeval
/* the extern "C" declaration is missing in lwip/netdb.h */
extern "C" {
#include <lwip/netdb.h>
}
#include <lwip_legacy/genode.h>
#include <lwip/sockets.h>
/* lwip and libc have different definitions for the FD_* macros and renaming
* of the macros is not possible, so wrapper functions are needed at this
* place */
static inline void lwip_FD_ZERO(lwip_fd_set *set)
{
FD_ZERO(set);
}
static inline bool lwip_FD_ISSET(int lwip_fd, lwip_fd_set *set)
{
return FD_ISSET(lwip_fd, set);
}
static inline void lwip_FD_SET(int lwip_fd, lwip_fd_set *set)
{
FD_SET(lwip_fd, set);
}
static constexpr long lwip_FIONBIO = FIONBIO;
static constexpr long lwip_FIONREAD = FIONREAD;
static constexpr int lwip_O_NONBLOCK = O_NONBLOCK;
/* undefine lwip type names that are also defined in libc headers and have
* been renamed to lwip_*() */
#undef addrinfo
#undef fd_set
#undef hostent
#undef linger
#undef sockaddr
#undef timeval
/* undefine lwip macros that are also defined in libc headers and cannot be
* renamed */
#undef AF_INET6
#undef BIG_ENDIAN
#undef BYTE_ORDER
#undef FD_CLR
#undef FD_ISSET
#undef FD_SET
#undef FD_ZERO
#undef FIONBIO
#undef FIONREAD
#undef O_NDELAY
#undef O_NONBLOCK
#undef HOST_NOT_FOUND
#undef IOCPARM_MASK
#undef IOC_VOID
#undef IOC_OUT
#undef IOC_IN
#undef _IO
#undef _IOR
#undef _IOW
#undef LITTLE_ENDIAN
#undef MSG_DONTWAIT
#undef MSG_OOB
#undef MSG_PEEK
#undef MSG_WAITALL
#undef NO_DATA
#undef NO_RECOVERY
#undef EAI_FAIL
#undef EAI_MEMORY
#undef EAI_NONAME
#undef EAI_SERVICE
#undef SIOCATMARK
#undef SIOCGHIWAT
#undef SIOCGLOWAT
#undef SIOCSHIWAT
#undef SIOCSLOWAT
#undef SOL_SOCKET
#undef TRY_AGAIN
/**********************
** Plugin interface **
**********************/
#include <libc-plugin/fd_alloc.h>
#include <libc-plugin/plugin_registry.h>
#include <assert.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
namespace {
/**
* For the lwip plugin, we only use the lwip file descriptor as context
*/
class Plugin_context : public Libc::Plugin_context
{
private:
int _lwip_fd;
public:
/**
* Constructor
*
* \param lwip_fd file descriptor used for interacting with the
* socket API of lwip
*/
Plugin_context(int lwip_fd) : _lwip_fd(lwip_fd) { }
int lwip_fd() const { return _lwip_fd; }
};
static inline Plugin_context *context(Libc::File_descriptor *fd)
{
return static_cast<Plugin_context *>(fd->context);
}
static inline int get_lwip_fd(Libc::File_descriptor *sockfdo)
{
return context(sockfdo)->lwip_fd();
}
struct Plugin : Libc::Plugin
{
/**
* Constructor
*/
Plugin();
bool supports_select(int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout) override;
bool supports_socket(int domain, int type, int protocol) override;
Libc::File_descriptor *accept(Libc::File_descriptor *sockfdo,
struct sockaddr *addr,
socklen_t *addrlen) override;
int bind(Libc::File_descriptor *sockfdo,
const struct sockaddr *addr,
socklen_t addrlen) override;
int close(Libc::File_descriptor *fdo) override;
int connect(Libc::File_descriptor *sockfdo,
const struct sockaddr *addr,
socklen_t addrlen) override;
int fcntl(Libc::File_descriptor *sockfdo, int cmd, long val) override;
int getpeername(Libc::File_descriptor *sockfdo,
struct sockaddr *addr,
socklen_t *addrlen) override;
int getsockname(Libc::File_descriptor *sockfdo,
struct sockaddr *addr,
socklen_t *addrlen) override;
int getsockopt(Libc::File_descriptor *sockfdo, int level,
int optname, void *optval,
socklen_t *optlen) override;
int ioctl(Libc::File_descriptor *sockfdo, int request, char *argp) override;
int listen(Libc::File_descriptor *sockfdo, int backlog) override;
ssize_t read(Libc::File_descriptor *fdo, void *buf, ::size_t count) override;
int shutdown(Libc::File_descriptor *fdo, int) override;
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout) override;
ssize_t send(Libc::File_descriptor *, const void *buf, ::size_t len, int flags) override;
ssize_t sendto(Libc::File_descriptor *, const void *buf,
::size_t len, int flags,
const struct sockaddr *dest_addr,
socklen_t addrlen) override;
ssize_t recv(Libc::File_descriptor *, void *buf, ::size_t len, int flags) override;
ssize_t recvfrom(Libc::File_descriptor *, void *buf, ::size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen) override;
int setsockopt(Libc::File_descriptor *sockfdo, int level,
int optname, const void *optval,
socklen_t optlen) override;
Libc::File_descriptor *socket(int domain, int type, int protocol) override;
ssize_t write(Libc::File_descriptor *fdo, const void *buf, ::size_t count) override;
};
Plugin::Plugin()
{
Genode::log("using the lwIP libc plugin");
lwip_tcpip_init();
}
bool Plugin::supports_select(int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout)
{
Libc::File_descriptor *fdo;
/* return true if any file descriptor which is marked set in one of
* the sets belongs to this plugin */
for (int libc_fd = 0; libc_fd < nfds; libc_fd++) {
if (FD_ISSET(libc_fd, readfds)
|| FD_ISSET(libc_fd, writefds) || FD_ISSET(libc_fd, exceptfds)) {
fdo = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
if (fdo && (fdo->plugin == this)) {
return true;
}
}
}
return false;
}
bool Plugin::supports_socket(int domain, int, int)
{
if (domain == AF_INET)
return true;
return false;
}
Libc::File_descriptor *Plugin::accept(Libc::File_descriptor *sockfdo,
struct sockaddr *addr, socklen_t *addrlen)
{
int lwip_fd = lwip_accept(get_lwip_fd(sockfdo), (struct lwip_sockaddr*)addr, addrlen);
if (lwip_fd == -1) {
return 0;
}
Plugin_context *context = new (Genode::env()->heap()) Plugin_context(lwip_fd);
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->alloc(this, context);
if (!fd)
Genode::error("could not allocate file descriptor");
return fd;
}
int Plugin::bind(Libc::File_descriptor *sockfdo, const struct sockaddr *addr,
socklen_t addrlen)
{
return lwip_bind(get_lwip_fd(sockfdo), (struct lwip_sockaddr*)addr, addrlen);
}
int Plugin::close(Libc::File_descriptor *fdo)
{
int result = lwip_close(get_lwip_fd(fdo));
if (context(fdo))
Genode::destroy(Genode::env()->heap(), context(fdo));
Libc::file_descriptor_allocator()->free(fdo);
return result;
}
int Plugin::connect(Libc::File_descriptor *sockfdo,
const struct sockaddr *addr,
socklen_t addrlen)
{
return lwip_connect(get_lwip_fd(sockfdo), (struct lwip_sockaddr*)addr, addrlen);
}
int Plugin::fcntl(Libc::File_descriptor *sockfdo, int cmd, long val)
{
int s = get_lwip_fd(sockfdo);
int result = -1;
switch (cmd) {
case F_GETFL:
/* lwip_fcntl() supports only the 'O_NONBLOCK' flag */
result = lwip_fcntl(s, cmd, val);
if (result == lwip_O_NONBLOCK)
result = O_NONBLOCK;
break;
case F_SETFL:
/*
* lwip_fcntl() supports only the 'O_NONBLOCK' flag and only if
* no other flag is set.
*/
result = lwip_fcntl(s, cmd, (val & O_NONBLOCK) ? lwip_O_NONBLOCK : 0);
break;
default:
Genode::error("libc_lwip: unsupported fcntl() request: ", cmd);
break;
}
return result;
}
int Plugin::getpeername(Libc::File_descriptor *sockfdo,
struct sockaddr *addr,
socklen_t *addrlen)
{
return lwip_getpeername(get_lwip_fd(sockfdo), (struct lwip_sockaddr*)addr, addrlen);
}
int Plugin::getsockname(Libc::File_descriptor *sockfdo,
struct sockaddr *addr,
socklen_t *addrlen)
{
return lwip_getsockname(get_lwip_fd(sockfdo), (struct lwip_sockaddr*)addr, addrlen);
}
int Plugin::getsockopt(Libc::File_descriptor *sockfdo, int level,
int optname, void *optval, socklen_t *optlen)
{
return lwip_getsockopt(get_lwip_fd(sockfdo), level, optname, optval, optlen);
}
int Plugin::ioctl(Libc::File_descriptor *sockfdo, int request, char *argp)
{
switch (request) {
case FIONBIO:
return lwip_ioctl(get_lwip_fd(sockfdo), lwip_FIONBIO, argp);
break;
case FIONREAD:
return lwip_ioctl(get_lwip_fd(sockfdo), lwip_FIONREAD, argp);;
break;
default:
Genode::error("unsupported ioctl() request");
errno = ENOSYS;
return -1;
}
}
int Plugin::listen(Libc::File_descriptor *sockfdo, int backlog)
{
return lwip_listen(get_lwip_fd(sockfdo), backlog);
}
ssize_t Plugin::read(Libc::File_descriptor *fdo, void *buf, ::size_t count)
{
return lwip_read(get_lwip_fd(fdo), buf, count);
}
int Plugin::shutdown(Libc::File_descriptor *sockfdo, int how)
{
return lwip_shutdown(get_lwip_fd(sockfdo), how);
}
int Plugin::select(int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout)
{
Libc::File_descriptor *fdo;
lwip_fd_set lwip_readfds;
lwip_fd_set lwip_writefds;
lwip_fd_set lwip_exceptfds;
int libc_fd;
int lwip_fd;
int highest_lwip_fd = -2;
int result;
lwip_FD_ZERO(&lwip_readfds);
lwip_FD_ZERO(&lwip_writefds);
lwip_FD_ZERO(&lwip_exceptfds);
for (libc_fd = 0; libc_fd < nfds; libc_fd++) {
fdo = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
/* handle only libc_fds that belong to this plugin */
if (!fdo || (fdo->plugin != this))
continue;
if (FD_ISSET(libc_fd, readfds) ||
FD_ISSET(libc_fd, writefds) ||
FD_ISSET(libc_fd, exceptfds)) {
lwip_fd = get_lwip_fd(fdo);
if (lwip_fd > highest_lwip_fd) {
highest_lwip_fd = lwip_fd;
}
if (FD_ISSET(libc_fd, readfds)) {
lwip_FD_SET(lwip_fd, &lwip_readfds);
}
if (FD_ISSET(libc_fd, writefds)) {
lwip_FD_SET(lwip_fd, &lwip_writefds);
}
if (FD_ISSET(libc_fd, exceptfds)) {
lwip_FD_SET(lwip_fd, &lwip_exceptfds);
}
}
}
result = lwip_select(highest_lwip_fd + 1,
&lwip_readfds,
&lwip_writefds,
&lwip_exceptfds,
(struct lwip_timeval*)timeout);
if (result > 0) {
/* clear result sets */
FD_ZERO(readfds);
FD_ZERO(writefds);
FD_ZERO(exceptfds);
for (lwip_fd = 0; lwip_fd <= highest_lwip_fd; lwip_fd++) {
/* find an lwip_fd which is in the set */
if (lwip_FD_ISSET(lwip_fd, &lwip_readfds) ||
lwip_FD_ISSET(lwip_fd, &lwip_writefds) ||
lwip_FD_ISSET(lwip_fd, &lwip_exceptfds)) {
/* find matching libc_fd for lwip_fd */
for (libc_fd = 0; libc_fd < nfds; libc_fd++) {
fdo = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
if (fdo && (fdo->plugin == this) &&
(get_lwip_fd(fdo) == lwip_fd)) {
if (lwip_FD_ISSET(lwip_fd, &lwip_readfds)) {
FD_SET(libc_fd, readfds);
}
if (lwip_FD_ISSET(lwip_fd, &lwip_writefds)) {
FD_SET(libc_fd, writefds);
}
if (lwip_FD_ISSET(lwip_fd, &lwip_exceptfds)) {
FD_SET(libc_fd, exceptfds);
}
}
}
}
}
}
return result;
}
ssize_t Plugin::recv(Libc::File_descriptor *sockfdo, void *buf, ::size_t len, int flags)
{
return lwip_recv(get_lwip_fd(sockfdo), buf, len, flags);
}
ssize_t Plugin::recvfrom(Libc::File_descriptor *sockfdo, void *buf, ::size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen)
{
return lwip_recvfrom(get_lwip_fd(sockfdo), buf, len, flags,
(struct lwip_sockaddr *)src_addr, addrlen);
}
ssize_t Plugin::send(Libc::File_descriptor *sockfdo, const void *buf, ::size_t len, int flags)
{
return lwip_send(get_lwip_fd(sockfdo), buf, len, flags);
}
ssize_t Plugin::sendto(Libc::File_descriptor *sockfdo, const void *buf,
::size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen)
{
return lwip_sendto(get_lwip_fd(sockfdo), buf, len, flags,
(struct lwip_sockaddr *)dest_addr, addrlen);
}
int Plugin::setsockopt(Libc::File_descriptor *sockfdo, int level,
int optname, const void *optval,
socklen_t optlen)
{
return lwip_setsockopt(get_lwip_fd(sockfdo), level, optname, optval, optlen);
}
Libc::File_descriptor *Plugin::socket(int domain, int type, int protocol)
{
int lwip_fd = lwip_socket(domain, type, protocol);
if (lwip_fd == -1) {
Genode::error("lwip_socket() failed");
return 0;
}
Plugin_context *context = new (Genode::env()->heap()) Plugin_context(lwip_fd);
return Libc::file_descriptor_allocator()->alloc(this, context);
}
ssize_t Plugin::write(Libc::File_descriptor *fdo, const void *buf, ::size_t count)
{
return lwip_write(get_lwip_fd(fdo), buf, count);
}
} /* unnamed namespace */
void create_lwip_plugin()
{
static Plugin lwip_plugin;
}

View File

@ -1,37 +0,0 @@
/*
* \brief lwip loopback interface initialization
* \author Christian Prochaska
* \date 2010-04-29
*
*/
/*
* Copyright (C) 2010-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#include <base/log.h>
#include <lwip_legacy/genode.h>
extern void create_lwip_plugin();
void __attribute__((constructor)) init_loopback(void)
{
Genode::log(__func__);
/* make sure the libc_lwip plugin has been created */
create_lwip_plugin();
/**
* As of lwip-1.4.x this is not needed anymore because lwip
* now always creates a loopback device. This plug-in will
* be removed in the future but for now keep it around so
* we currently do not need to update the other targets that
* depend on it.
*
* lwip_loopback_init();
*/
}

View File

@ -1,353 +0,0 @@
/*
* \brief Libc plugin providing lwIP's DNS server address in the
* '/socket/nameserver' file
* \author Christian Prochaska
* \date 2013-05-02
*/
/*
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* lwip includes */
#include <lwip/err.h>
#include <lwip/ip_addr.h>
#include <lwip/dns.h>
/* fix redefinition warnings */
#undef LITTLE_ENDIAN
#undef BIG_ENDIAN
#undef BYTE_ORDER
/* libc plugin interface */
#include <libc-plugin/plugin.h>
#include <libc-plugin/fd_alloc.h>
/* libc includes */
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
/* Genode includes */
#include <base/attached_rom_dataspace.h>
#include <base/env.h>
#include <base/heap.h>
#include <util/misc_math.h>
#include <base/log.h>
#include <parent/parent.h>
#include <nic/packet_allocator.h>
#include <util/string.h>
#include <lwip_legacy/genode.h>
#undef AF_INET6
#undef MSG_PEEK
#undef MSG_WAITALL
#undef MSG_OOB
#undef MSG_DONTWAIT
namespace Lwip {
extern "C" {
#include <lwip/sockets.h>
#include <lwip/api.h>
}
}
extern void create_lwip_plugin();
namespace {
class Plugin_context : public Libc::Plugin_context
{
private:
int _status_flags;
off_t _seek_offset;
public:
Plugin_context() : _status_flags(0), _seek_offset(0) { }
/**
* Set/get file status status flags
*/
void status_flags(int flags) { _status_flags = flags; }
int status_flags() { return _status_flags; }
/**
* Set seek offset
*/
void seek_offset(size_t seek_offset) { _seek_offset = seek_offset; }
/**
* Return seek offset
*/
off_t seek_offset() const { return _seek_offset; }
/**
* Advance current seek position by 'incr' number of bytes
*/
void advance_seek_offset(size_t incr)
{
_seek_offset += incr;
}
void infinite_seek_offset()
{
_seek_offset = ~0;
}
};
static inline Plugin_context *context(Libc::File_descriptor *fd)
{
return static_cast<Plugin_context *>(fd->context);
}
class Plugin : public Libc::Plugin
{
private:
Genode::Constructible<Genode::Heap> _heap;
/**
* File name this plugin feels responsible for
*/
static char const *_file_name() { return "/socket/nameserver"; }
const char *_file_content()
{
static char result[32];
ip_addr_t nameserver_ip = dns_getserver(0);
snprintf(result, sizeof(result), "%s\n",
ipaddr_ntoa(&nameserver_ip));
return result;
}
::off_t _file_size(Libc::File_descriptor *fd)
{
struct stat stat_buf;
if (fstat(fd, &stat_buf) == -1)
return -1;
return stat_buf.st_size;
}
public:
/**
* Constructor
*/
Plugin() { }
bool supports_stat(const char *path)
{
return (Genode::strcmp(path, "/socket") == 0) ||
(Genode::strcmp(path, _file_name()) == 0);
}
bool supports_open(const char *path, int flags)
{
return (Genode::strcmp(path, _file_name()) == 0);
}
Libc::File_descriptor *open(const char *pathname, int flags)
{
Plugin_context *context = new (*_heap) Plugin_context;
context->status_flags(flags);
return Libc::file_descriptor_allocator()->alloc(this, context);
}
int close(Libc::File_descriptor *fd)
{
Genode::destroy(*_heap, context(fd));
Libc::file_descriptor_allocator()->free(fd);
return 0;
}
int stat(const char *path, struct stat *buf)
{
if (buf) {
Genode::memset(buf, 0, sizeof(struct stat));
if (Genode::strcmp(path, "/socket") == 0)
buf->st_mode = S_IFDIR;
else if (Genode::strcmp(path, _file_name()) == 0) {
buf->st_mode = S_IFREG;
buf->st_size = strlen(_file_content()) + 1;
} else {
errno = ENOENT;
return -1;
}
}
return 0;
}
int fstat(Libc::File_descriptor *fd, struct stat *buf)
{
if (buf) {
Genode::memset(buf, 0, sizeof(struct stat));
buf->st_mode = S_IFREG;
buf->st_size = strlen(_file_content()) + 1;
}
return 0;
}
::off_t lseek(Libc::File_descriptor *fd, ::off_t offset, int whence)
{
switch (whence) {
case SEEK_SET:
context(fd)->seek_offset(offset);
return offset;
case SEEK_CUR:
context(fd)->advance_seek_offset(offset);
return context(fd)->seek_offset();
case SEEK_END:
if (offset != 0) {
errno = EINVAL;
return -1;
}
context(fd)->infinite_seek_offset();
return _file_size(fd);
default:
errno = EINVAL;
return -1;
}
}
ssize_t read(Libc::File_descriptor *fd, void *buf, ::size_t count)
{
::off_t seek_offset = context(fd)->seek_offset();
if (seek_offset >= _file_size(fd))
return 0;
const char *content = _file_content();
count = Genode::min((::off_t)count, _file_size(fd) - seek_offset);
memcpy(buf, &content[seek_offset], count);
context(fd)->advance_seek_offset(count);
return count;
}
int fcntl(Libc::File_descriptor *fd, int cmd, long arg)
{
switch (cmd) {
case F_GETFL: return context(fd)->status_flags();
default: Genode::error("fcntl(): command ", cmd, " not supported", cmd); return -1;
}
}
void init(Libc::Env &env) override
{
_heap.construct(env.ram(), env.rm());
enum { BUF_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE * 128 };
Genode::log(__func__);
char ip_addr_str[16] = {0};
char netmask_str[16] = {0};
char gateway_str[16] = {0};
genode_int32_t ip_addr = 0;
genode_int32_t netmask = 0;
genode_int32_t gateway = 0;
Genode::Number_of_bytes tx_buf_size(BUF_SIZE);
Genode::Number_of_bytes rx_buf_size(BUF_SIZE);
try {
Genode::Attached_rom_dataspace config(env, "config");
Genode::Xml_node libc_node = config.xml().sub_node("libc");
try {
libc_node.attribute("ip_addr").value(ip_addr_str, sizeof(ip_addr_str));
} catch(...) { }
try {
libc_node.attribute("netmask").value(netmask_str, sizeof(netmask_str));
} catch(...) { }
try {
libc_node.attribute("gateway").value(gateway_str, sizeof(gateway_str));
} catch(...) { }
try {
libc_node.attribute("tx_buf_size").value(&tx_buf_size);
} catch(...) { }
try {
libc_node.attribute("rx_buf_size").value(&rx_buf_size);
} catch(...) { }
/* either none or all 3 interface attributes must exist */
if ((strlen(ip_addr_str) != 0) ||
(strlen(netmask_str) != 0) ||
(strlen(gateway_str) != 0)) {
if (strlen(ip_addr_str) == 0) {
Genode::error("missing \"ip_addr\" attribute. Ignoring network interface config.");
throw Genode::Xml_node::Nonexistent_attribute();
} else if (strlen(netmask_str) == 0) {
Genode::error("missing \"netmask\" attribute. Ignoring network interface config.");
throw Genode::Xml_node::Nonexistent_attribute();
} else if (strlen(gateway_str) == 0) {
Genode::error("missing \"gateway\" attribute. Ignoring network interface config.");
throw Genode::Xml_node::Nonexistent_attribute();
}
} else
throw -1;
Genode::log("static network interface: "
"ip_addr=", Genode::Cstring(ip_addr_str), " "
"netmask=", Genode::Cstring(netmask_str), " "
"gateway=", Genode::Cstring(gateway_str));
genode_uint32_t ip, nm, gw;
ip = inet_addr(ip_addr_str);
nm = inet_addr(netmask_str);
gw = inet_addr(gateway_str);
if (ip == INADDR_NONE || nm == INADDR_NONE || gw == INADDR_NONE) {
Genode::error("invalid network interface config");
throw -1;
} else {
ip_addr = ip;
netmask = nm;
gateway = gw;
}
}
catch (...) {
Genode::log("Using DHCP for interface configuration.");
}
/* make sure the libc_lwip plugin has been created */
create_lwip_plugin();
try {
lwip_nic_init(ip_addr, netmask, gateway,
(Genode::size_t)tx_buf_size, (Genode::size_t)rx_buf_size);
}
catch (Genode::Service_denied) { /* ignore for now */ }
}
};
} /* unnamed namespace */
void __attribute__((constructor)) init_libc_lwip_dhcp(void)
{
static Plugin plugin;
}

View File

@ -1,13 +0,0 @@
The write offset was not always reset after a write finished resulting in the
failed assertion "already writing or closing".
--- a/src/api/api_msg.c
+++ b/src/api/api_msg.c
@@ -1340,6 +1340,7 @@ err_mem:
and back to application task */
conn->current_msg->err = err;
conn->current_msg = NULL;
+ conn->write_offset = 0;
conn->state = NETCONN_NONE;
#if LWIP_TCPIP_CORE_LOCKING
if ((conn->flags & NETCONN_FLAG_WRITE_DELAYED) != 0)

View File

@ -1,15 +0,0 @@
--- a/src/include/lwip/arch.h
+++ b/src/include/lwip/arch.h
@@ -208,6 +208,12 @@ extern "C" {
extern int errno;
#endif
+#else
+
+#include <errno.h>
+/* errno codes which are not defined in Genode libc's errno.h */
+#define ENSRNOTFOUND 163 /* Domain name not found */
+
#endif /* LWIP_PROVIDE_ERRNO */
#ifdef __cplusplus

View File

@ -1,30 +0,0 @@
/*
* \brief LwIP Genode ethernet interface
* \author Stefan Kalkowski
* \date 2009-11-05
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _LWIP__NIC_H_
#define _LWIP__NIC_H_
struct netif_buf_sizes {
__SIZE_TYPE__ tx_buf_size;
__SIZE_TYPE__ rx_buf_size;
};
/**
* Initializes the genode nic backend.
*
* \param netif pointer to struct, where nic related stuff is registered.
*/
err_t genode_netif_init(struct netif *netif);
#endif //_LWIP__NIC_H_

View File

@ -1,119 +0,0 @@
/*
* \brief Ring buffer implementation.
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2009-10-29
*
* This ring buffer implementation is taken from the os repository.
* In contrast to the original implementation this one lets pass
* timeouts.
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef __LWIP__INCLUDE__RING_BUFFER_H__
#define __LWIP__INCLUDE__RING_BUFFER_H__
#include <base/exception.h>
#include <util/string.h>
#include <os/timed_semaphore.h>
namespace Lwip {
/**
* Ring buffer
*
* The ring buffer manages its elements as values.
* When inserting an element, a copy of the element is
* stored in the buffer. Hence, the ring buffer is suited
* for simple plain-data element types.
*/
class Ring_buffer
{
private:
enum Constants { QUEUE_SIZE=128 };
int _head;
int _tail;
Genode::Timed_semaphore _sem; /* element counter */
Genode::Lock _head_lock; /* synchronize add */
void* _queue[QUEUE_SIZE];
public:
class Overflow : public Genode::Exception { };
static const Genode::Alarm::Time NO_BLOCK = 1;
/**
* Constructor
*/
Ring_buffer() : _head(0), _tail(0)
{
Genode::memset(_queue, 0, sizeof(_queue));
}
/**
* Place element into ring buffer
*
* If the ring buffer is full, this function
* throws an Overflow exception.
*/
void add(void* ev)
{
Genode::Lock::Guard lock_guard(_head_lock);
if ((_head + 1)%QUEUE_SIZE != _tail) {
_queue[_head] = ev;
_head = (_head + 1)%QUEUE_SIZE;
_sem.up();
} else
throw Overflow();
}
/**
* Take element from ring buffer
*
* \return element
*
* If the ring buffer is empty, this function
* blocks until an element gets available.
*/
Genode::Alarm::Time get(void* *ev, Genode::Alarm::Time t)
{
Genode::Alarm::Time time;
if (t == NO_BLOCK) {
time = _sem.down(0);
} else if (t == 0) {
time = Genode::Timeout_thread::alarm_timer()->time();
_sem.down();
time = Genode::Timeout_thread::alarm_timer()->time() - time;
} else {
time = _sem.down(t);
}
Genode::Lock::Guard lock_guard(_head_lock);
*ev = _queue[_tail];
_tail = (_tail + 1)%QUEUE_SIZE;
return time;
}
/**
* Return true if ring buffer is empty
*/
bool empty() { return _tail == _head; }
};
}
#endif //__LWIP__INCLUDE__RING_BUFFER_H_

View File

@ -1,43 +0,0 @@
/*
* \brief Thread implementation for LwIP threads.
* \author Stefan Kalkowski
* \date 2009-11-14
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef __LWIP__INCLUDE__THREAD_H__
#define __LWIP__INCLUDE__THREAD_H__
#include <base/thread.h>
extern "C" {
#include <lwip/sys.h>
}
namespace Lwip {
class Lwip_thread : public Genode::Thread_deprecated<16384>
{
private:
void (*_thread)(void *arg);
void *_arg;
public:
Lwip_thread(const char *name,
void (* thread)(void *arg),
void *arg)
: Genode::Thread_deprecated<16384>(name), _thread(thread), _arg(arg) { }
void entry() { _thread(_arg); }
};
}
#endif //__LWIP__INCLUDE__THREAD_H__

View File

@ -1,22 +0,0 @@
/*
* \brief Enable debugging output
* \author Sebastian Sumpf
* \date 2012-09-26
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _LWIP__VERBOSE_H_
#define _LWIP__VERBOSE_H_
/**
* Set to one for more output
*/
static int verbose = 0;
#endif //_LWIP__VERBOSE_H_

View File

@ -1,39 +0,0 @@
--- a/src/api/sockets.c
+++ b/src/api/sockets.c
@@ -243,6 +243,9 @@ static const int err_to_errno_table[] = {
set_errno(sk->err); \
} while (0)
+/* function to notify libc about a socket event */
+extern void (*libc_select_notify)();
+
/* Forward delcaration of some functions */
static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len);
static void lwip_getsockopt_internal(void *arg);
@@ -1316,7 +1319,7 @@ return_copy_fdsets:
* Processes recvevent (data available) and wakes up tasks waiting for select.
*/
static void
-event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
+orig_event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
{
int s;
struct lwip_sock *sock;
@@ -1431,6 +1434,17 @@ again:
SYS_ARCH_UNPROTECT(lev);
}
+/* Wrapper for the original event_callback() function that additionally calls
+ * libc_select_notify()
+ */
+static void
+event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
+{
+ orig_event_callback(conn, evt, len);
+ if (libc_select_notify)
+ libc_select_notify();
+}
+
/**
* Unimplemented: Close one end of a full-duplex connection.
* Currently, the full connection is closed.

View File

@ -1,26 +0,0 @@
Avoid assertion on nonblocking connect()
From: Christian Prochaska <christian.prochaska@genode-labs.com>
When calling 'connect()' in nonblocking mode and the connection has been
established, don't call 'tcp_connect()' again, which would trigger an
assertion with the message 'tcp_connect: can only connect from state
CLOSED'.
---
src/api/api_msg.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/api/api_msg.c b/src/api/api_msg.c
index c00222c..d05a5ae 100644
--- a/src/api/api_msg.c
+++ b/src/api/api_msg.c
@@ -1008,7 +1008,8 @@ lwip_netconn_do_connect(struct api_msg_msg *msg)
#if LWIP_TCP
case NETCONN_TCP:
/* Prevent connect while doing any other action. */
- if (msg->conn->state != NETCONN_NONE) {
+ if ((msg->conn->state != NETCONN_NONE) ||
+ ((msg->conn->pcb.tcp->state == ESTABLISHED) && netconn_is_nonblocking(msg->conn))) {
msg->err = ERR_ISCONN;
} else {
setup_tcp(msg->conn);

View File

@ -1,339 +0,0 @@
/*
* \brief LwIP ethernet interface
* \author Stefan Kalkowski
* \date 2009-11-05
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* LwIP includes */
extern "C" {
#include <lwip/opt.h>
#include <lwip/def.h>
#include <lwip/mem.h>
#include <lwip/pbuf.h>
#include <lwip/sys.h>
#include <lwip/stats.h>
#include <lwip/snmp.h>
#include <netif/etharp.h>
#include <netif/ppp_oe.h>
#include <nic.h>
#include <verbose.h>
}
/* Genode includes */
#include <base/thread.h>
#include <base/log.h>
#include <nic/packet_allocator.h>
#include <nic_session/connection.h>
extern "C" {
static void genode_netif_input(struct netif *netif);
void lwip_nic_link_state_changed(int state);
}
/*
* Thread, that receives packets by the nic-session interface.
*/
class Nic_receiver_thread : public Genode::Thread_deprecated<8192>
{
private:
typedef Nic::Packet_descriptor Packet_descriptor;
Nic::Connection *_nic; /* nic-session */
Packet_descriptor _rx_packet; /* actual packet received */
struct netif *_netif; /* LwIP network interface structure */
Genode::Signal_receiver _sig_rec;
Genode::Io_signal_dispatcher<Nic_receiver_thread> _link_state_dispatcher;
Genode::Io_signal_dispatcher<Nic_receiver_thread> _rx_packet_avail_dispatcher;
Genode::Io_signal_dispatcher<Nic_receiver_thread> _rx_ready_to_ack_dispatcher;
void _handle_rx_packet_avail(unsigned)
{
while (_nic->rx()->packet_avail() && _nic->rx()->ready_to_ack()) {
_rx_packet = _nic->rx()->get_packet();
genode_netif_input(_netif);
_nic->rx()->acknowledge_packet(_rx_packet);
}
}
void _handle_rx_read_to_ack(unsigned) { _handle_rx_packet_avail(0); }
void _handle_link_state(unsigned)
{
lwip_nic_link_state_changed(_nic->link_state());
}
void _tx_ack(bool block = false)
{
/* check for acknowledgements */
while (nic()->tx()->ack_avail() || block) {
Packet_descriptor acked_packet = nic()->tx()->get_acked_packet();
nic()->tx()->release_packet(acked_packet);
block = false;
}
}
public:
Nic_receiver_thread(Nic::Connection *nic, struct netif *netif)
:
Genode::Thread_deprecated<8192>("nic-recv"), _nic(nic), _netif(netif),
_link_state_dispatcher(_sig_rec, *this, &Nic_receiver_thread::_handle_link_state),
_rx_packet_avail_dispatcher(_sig_rec, *this, &Nic_receiver_thread::_handle_rx_packet_avail),
_rx_ready_to_ack_dispatcher(_sig_rec, *this, &Nic_receiver_thread::_handle_rx_read_to_ack)
{
_nic->link_state_sigh(_link_state_dispatcher);
_nic->rx_channel()->sigh_packet_avail(_rx_packet_avail_dispatcher);
_nic->rx_channel()->sigh_ready_to_ack(_rx_ready_to_ack_dispatcher);
}
void entry();
Nic::Connection *nic() { return _nic; };
Packet_descriptor rx_packet() { return _rx_packet; };
Packet_descriptor alloc_tx_packet(Genode::size_t size)
{
while (true) {
try {
Packet_descriptor packet = nic()->tx()->alloc_packet(size);
return packet;
} catch(Nic::Session::Tx::Source::Packet_alloc_failed) {
/* packet allocator exhausted, wait for acknowledgements */
_tx_ack(true);
}
}
}
void submit_tx_packet(Packet_descriptor packet)
{
nic()->tx()->submit_packet(packet);
/* check for acknowledgements */
_tx_ack();
}
char *content(Packet_descriptor packet) {
return nic()->tx()->packet_content(packet); }
};
/*
* C-interface
*/
extern "C" {
/**
* This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this genode_netif
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
Nic_receiver_thread *th = reinterpret_cast<Nic_receiver_thread*>(netif->state);
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
Nic::Packet_descriptor tx_packet = th->alloc_tx_packet(p->tot_len);
char *tx_content = th->content(tx_packet);
/*
* Iterate through all pbufs and
* copy payload into packet's payload
*/
for(struct pbuf *q = p; q != NULL; q = q->next) {
char *src = (char*) q->payload;
Genode::memcpy(tx_content, src, q->len);
tx_content += q->len;
}
/* Submit packet */
th->submit_tx_packet(tx_packet);
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.xmit);
return ERR_OK;
}
/**
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
* @param netif the lwip network interface structure for this genode_netif
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
static struct pbuf *
low_level_input(struct netif *netif)
{
Nic_receiver_thread *th = reinterpret_cast<Nic_receiver_thread*>(netif->state);
Nic::Connection *nic = th->nic();
Nic::Packet_descriptor rx_packet = th->rx_packet();
char *rx_content = nic->rx()->packet_content(rx_packet);
u16_t len = rx_packet.size();
#if ETH_PAD_SIZE
len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
#endif
/* We allocate a pbuf chain of pbufs from the pool. */
struct pbuf *p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
if (p) {
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
/*
* We iterate over the pbuf chain until we have read the entire
* packet into the pbuf.
*/
for(struct pbuf *q = p; q != 0; q = q->next) {
char *dst = (char*)q->payload;
Genode::memcpy(dst, rx_content, q->len);
rx_content += q->len;
}
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.recv);
} else {
LINK_STATS_INC(link.memerr);
LINK_STATS_INC(link.drop);
}
return p;
}
/**
* This function should be called when a packet is ready to be read
* from the interface. It uses the function low_level_input() that
* should handle the actual reception of bytes from the network
* interface. Then the type of the received packet is determined and
* the appropriate input function is called.
*
* @param netif the lwip network interface structure for this genode_netif
*/
static void
genode_netif_input(struct netif *netif)
{
/*
* Move received packet into a new pbuf,
* if something went wrong, return silently
*/
struct pbuf *p = low_level_input(netif);
/* No packet could be read, silently ignore this */
if (p == NULL) return;
if (netif->input(p, netif) != ERR_OK) {
if (verbose)
Genode::error("genode_netif_input: input error");
pbuf_free(p);
p = 0;
}
}
/**
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this genode_netif
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t genode_netif_init(struct netif *netif)
{
using namespace Genode;
LWIP_ASSERT("netif != NULL", (netif != NULL));
/* Initialize nic-session */
Nic::Packet_allocator *tx_block_alloc = new (env()->heap())
Nic::Packet_allocator(env()->heap());
struct netif_buf_sizes *nbs = (struct netif_buf_sizes *) netif->state;
Nic::Connection *nic = 0;
try {
nic = new (env()->heap()) Nic::Connection(tx_block_alloc,
nbs->tx_buf_size,
nbs->rx_buf_size);
}
catch (Service_denied) {
destroy(env()->heap(), tx_block_alloc);
return ERR_IF;
}
/* Setup receiver thread */
Nic_receiver_thread *th = new (env()->heap())
Nic_receiver_thread(nic, netif);
/* Store receiver thread address in user-defined netif struct part */
netif->state = (void*) th;
#if LWIP_NETIF_HOSTNAME
netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */
netif->name[0] = 'e';
netif->name[1] = 'n';
netif->output = etharp_output;
netif->linkoutput = low_level_output;
netif->mtu = 1500;
netif->hwaddr_len = ETHARP_HWADDR_LEN;
netif->flags = NETIF_FLAG_BROADCAST |
NETIF_FLAG_ETHARP |
NETIF_FLAG_LINK_UP;
/* Get MAC address from nic-session and set it accordingly */
Nic::Mac_address _mac = nic->mac_address();
for(int i=0; i<6; ++i)
netif->hwaddr[i] = _mac.addr[i];
th->start();
return ERR_OK;
}
} /* extern "C" */
void Nic_receiver_thread::entry()
{
while(true)
{
Genode::Signal sig = _sig_rec.wait_for_signal();
int num = sig.num();
Genode::Signal_dispatcher_base *dispatcher;
dispatcher = dynamic_cast<Genode::Signal_dispatcher_base *>(sig.context());
dispatcher->dispatch(num);
}
}

View File

@ -1,36 +0,0 @@
/*
* \brief Print function for debugging functionality of lwIP.
* \author Stefan Kalkowski
* \date 2009-10-26
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/printf.h>
#include <base/console.h>
#include <base/lock.h>
#include <base/env.h>
extern "C" {
/* LwIP includes */
#include <arch/cc.h>
/* Simply map to Genode's printf implementation */
void lwip_printf(const char *format, ...)
{
va_list list;
va_start(list, format);
Genode::vprintf(format, list);
va_end(list);
}
}

View File

@ -1,660 +0,0 @@
/*
* \brief Platform dependent function implementations for lwIP.
* \author Stefan Kalkowski
* \date 2009-10-26
*/
/*
* Copyright (C) 2009-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/log.h>
#include <base/env.h>
#include <base/lock.h>
#include <base/sleep.h>
#include <parent/parent.h>
#include <os/timed_semaphore.h>
/* LwIP includes */
#include <lwip_legacy/genode.h>
#include <ring_buffer.h>
#include <thread.h>
#include <verbose.h>
namespace Lwip {
class Mutex
{
public:
Genode::Lock lock;
int counter;
Genode::Thread *thread;
Mutex() : counter(0), thread((Genode::Thread*)-1) {}
};
/* LwIP's so called mailboxes map to a ring buffer in our case */
typedef Ring_buffer Mailbox;
}
/**
* Returns lock used to synchronize with tcpip thread's startup.
*/
static Genode::Lock *startup_lock()
{
static Genode::Lock _startup_lock(Genode::Lock::LOCKED);
return &_startup_lock;
}
/**
* Returns global mutex for lightweight protection mechanisms in LwIP.
*/
static Lwip::Mutex *global_mutex()
{
static Lwip::Mutex _mutex;
return &_mutex;
}
/**
* Used for startup synchronization by the tcpip thread.
*/
static void startup_done(void *arg)
{
startup_lock()->unlock();
}
using namespace Lwip;
extern "C" {
/* LwIP includes */
#include <lwip/opt.h>
#include <lwip/tcpip.h>
#include <lwip/err.h>
#include <lwip/sys.h>
#include <lwip/dhcp.h>
#include <arch/sys_arch.h>
#include <arch/cc.h>
#include <nic.h>
/*
* Sanitize check, whether somebody tries to use our LwIP backend,
* without the tcpip thread and synchronization primitives,
* we use LwIP multi-threaded anyway.
*/
#if NO_SYS
#error "You cannot use the Genode LwIP backend with NO_SYS!"
#endif //NO_SYS
#define netifapi_netif_set_link_up(n) netifapi_netif_common(n, netif_set_link_up, NULL)
#define netifapi_netif_set_link_down(n) netifapi_netif_common(n, netif_set_link_down, NULL)
static struct netif netif;
/*
* Callback function used when changing the interface state.
*/
static void status_callback(struct netif *netif)
{
static ip_addr_t ip_addr = { 0 };
if (ip_addr.addr != netif->ip_addr.addr) {
Genode::log("got IP address ",
ip4_addr1(&(netif->ip_addr)), ".",
ip4_addr2(&(netif->ip_addr)), ".",
ip4_addr3(&(netif->ip_addr)), ".",
ip4_addr4(&(netif->ip_addr)));
ip_addr.addr = netif->ip_addr.addr;
}
}
/*
* Callback function used when doing a link-state change.
*/
static void link_callback(struct netif *netif)
{
/*
* We call the status callback at this point to print
* the IP address because we may have got a new one,
* e.h., we joined another wireless network.
*/
status_callback(netif);
}
/********************
** Initialization **
********************/
/**
* Function needed by LwIP.
*/
void sys_init(void) {}
void lwip_tcpip_init()
{
/* call the tcpip initialization code and block, until it's initialized */
tcpip_init(startup_done, 0);
startup_lock()->lock();
}
/* in lwip/genode.h */
int lwip_nic_init(Genode::int32_t ip_addr,
Genode::int32_t netmask,
Genode::int32_t gateway,
Genode::size_t tx_buf_size,
Genode::size_t rx_buf_size)
{
struct ip_addr ip, nm, gw;
static struct netif_buf_sizes nbs;
nbs.tx_buf_size = tx_buf_size;
nbs.rx_buf_size = rx_buf_size;
ip.addr = ip_addr;
nm.addr = netmask;
gw.addr = gateway;
class Nic_not_availble { };
try {
/**
* Add Genode's nic, which uses the nic-session interface.
*
* LwIP recommends to use ethernet_input as packet pushing function
* for ethernet cards and ip_input for everything else.
* Nevertheless, when we use the tcpip synchronization subsystem,
* we should use tcpip_input anyway
*
* See: http://lwip.wikia.com/wiki/Writing_a_device_driver
*/
err_t ret = netifapi_netif_add(&netif, &ip, &nm, &gw, &nbs,
genode_netif_init, tcpip_input);
if (ret != ERR_OK)
throw Nic_not_availble();
/* Set Genode's nic as the default nic */
netifapi_netif_set_default(&netif);
/* If no static ip was set, we do dhcp */
if (!ip_addr) {
#if LWIP_DHCP
/* Register callback functions. */
netif.status_callback = status_callback;
netif.link_callback = link_callback;
netifapi_dhcp_start(&netif);
#else
/* no IP address - no networking */
return 1;
#endif /* LWIP_DHCP */
} else {
netifapi_netif_set_up(&netif);
}
} catch (Nic_not_availble) {
Genode::warning("NIC not available, loopback is used as default");
return 2;
}
return 0;
}
void lwip_nic_link_state_changed(int state)
{
if (state)
netifapi_netif_set_link_up(&netif);
else
netifapi_netif_set_link_down(&netif);
}
/***************
** Semaphore **
***************/
/**
* Creates and returns a new semaphore.
*
* \param count specifies the initial state of the semaphore.
* \return the semaphore, or SYS_SEM_NULL on error.
*/
err_t sys_sem_new(sys_sem_t* sem, u8_t count)
{
try {
Genode::Timed_semaphore *_sem = new (Genode::env()->heap())
Genode::Timed_semaphore(count);
sem->ptr = _sem;
return ERR_OK;
} catch (Genode::Allocator::Out_of_memory) {
Genode::warning(__func__, ": out of memory");
return ERR_MEM;
} catch (...) {
Genode::error(__func__, ": unknown exception occured!");
/* we just use a arbitrary value that is
* not defined in err.h */
return -32;
}
}
/**
* Frees a semaphore
*
* \param sem the semaphore to free
*/
void sys_sem_free(sys_sem_t* sem)
{
try {
Genode::Timed_semaphore *_sem =
reinterpret_cast<Genode::Timed_semaphore*>(sem->ptr);
if (_sem)
destroy(Genode::env()->heap(), _sem);
} catch (...) {
Genode::error(__func__, ": unknown exception occured!");
}
}
/**
* Signals (or releases) a semaphore.
*
*/
void sys_sem_signal(sys_sem_t* sem)
{
try {
Genode::Timed_semaphore *_sem =
reinterpret_cast<Genode::Timed_semaphore*>(sem->ptr);
if (!_sem) {
return;
}
_sem->up();
} catch (...) {
Genode::error(__func__, ": unknown exception occured!");
}
}
/**
* Checks if a semaphore is valid
*
* \param sem semaphore to check
*
* \return 1 if semaphore is valid, 0 otherwise.
*/
int sys_sem_valid(sys_sem_t* sem)
{
try {
Genode::Timed_semaphore *_sem =
reinterpret_cast<Genode::Timed_semaphore*>(sem->ptr);
if (_sem)
return 1;
} catch (...) { }
return 0;
}
/**
* Sets a semaphore to invalid
*
* \param sem semaphore to set invalid
*/
void sys_sem_set_invalid(sys_sem_t* sem)
{
sem->ptr = NULL;
}
/**
* Blocks the thread while waiting for the semaphore to be signaled.
*
* \param sem semaphore used to block on
* \param timeout specifies how many milliseconds the function should block.
* If timeout=0, then the function should block indefinitely.
* \return SYS_ARCH_TIMEOUT if the function times out. If the function
* acquires the semaphore, it should return how many
* milliseconds expired while waiting for the semaphore.
*/
u32_t sys_arch_sem_wait(sys_sem_t* sem, u32_t timeout)
{
using namespace Genode;
try {
Timed_semaphore *_sem = reinterpret_cast<Timed_semaphore*>(sem->ptr);
if (!_sem) {
return EINVAL;
}
/* If no timeout is requested, we have to track the time ourself */
if (!timeout) {
Alarm::Time starttime = Timeout_thread::alarm_timer()->time();
_sem->down();
return Timeout_thread::alarm_timer()->time() - starttime;
} else {
return _sem->down(timeout);
}
} catch (Timeout_exception) {
return SYS_ARCH_TIMEOUT;
} catch (...) {
Genode::error(__func__, ": unknown exception occured!");
return -1;
}
}
/**
* Enter critical section
*/
sys_prot_t sys_arch_protect(void)
{
if (global_mutex()->thread == Genode::Thread::myself())
return ++global_mutex()->counter;
global_mutex()->lock.lock();
global_mutex()->thread = Genode::Thread::myself();
return 0;
}
/**
* Leave critical section.
*/
void sys_arch_unprotect(sys_prot_t pval)
{
if (global_mutex()->thread != Genode::Thread::myself())
return;
if (global_mutex()->counter > 1)
global_mutex()->counter--;
else {
global_mutex()->counter = 0;
global_mutex()->thread = (Genode::Thread*)-1;
global_mutex()->lock.unlock();
}
}
/***************
** Mailboxes **
***************/
/**
* Allocate a new mailbox.
*
* \param size size of the mailbox
* \return a new mailbox, or SYS_MBOX_NULL on error.
*/
err_t sys_mbox_new(sys_mbox_t *mbox, int size) {
LWIP_UNUSED_ARG(size);
try {
Mailbox* _mbox = new (Genode::env()->heap()) Mailbox();
mbox->ptr = _mbox;
return ERR_OK;
} catch (Genode::Allocator::Out_of_memory) {
Genode::warning(__func__, ": out of memory");
return ERR_MEM;
} catch (...) {
Genode::error(__func__, ": unknown exception occured!");
return -32;
}
}
/**
* Free a mailbox.
*
* \param mbox mailbox to free
*/
void sys_mbox_free(sys_mbox_t* mbox)
{
try {
Mailbox* _mbox = reinterpret_cast<Mailbox*>(mbox->ptr);
if (_mbox)
destroy(Genode::env()->heap(), _mbox);
} catch (...) {
Genode::error(__func__, ": unknown exception occured!");
}
}
/**
* Checks if a mailbox is valid.
*
* \param mbox mailbox to check
*
* \return 1 if mailbox is valid, 0 otherwise.
*/
int sys_mbox_valid(sys_mbox_t* mbox)
{
try {
Mailbox* _mbox = reinterpret_cast<Mailbox*>(mbox->ptr);
if (_mbox) {
return 1;
}
} catch (...) { }
return 0;
}
/**
* Invalidate a mailbox
*
* Afterwards sys_mbox_valid() returns 0.
* ATTENTION: This does NOT mean that the mailbox shall be deallocated:
* sys_mbox_free() is always called before calling this function!
*
* \param mbox mailbox to set invalid
*/
void sys_mbox_set_invalid(sys_mbox_t* mbox)
{
mbox->ptr = NULL;
}
/**
* Posts the "msg" to the mailbox.
*
* \param mbox target mailbox
* \param msg message to post
*/
void sys_mbox_post(sys_mbox_t* mbox, void *msg)
{
while (true) {
try {
Mailbox* _mbox = reinterpret_cast<Mailbox*>(mbox->ptr);
if (!_mbox) {
return;
}
_mbox->add(msg);
return;
} catch (Mailbox::Overflow) {
if (verbose)
Genode::warning(__func__, ": overflow exception!");
} catch (...) {
Genode::error(__func__, ": unknown exception occured!");
}
}
}
/**
* Posts the "msg" to the mailbox, returns when it is full.
*
* \param mbox target mailbox
* \param msg message to post
*/
err_t sys_mbox_trypost(sys_mbox_t* mbox, void *msg)
{
try {
Mailbox* _mbox = reinterpret_cast<Mailbox*>(mbox->ptr);
if (!_mbox) {
return EINVAL;
}
_mbox->add(msg);
return ERR_OK;
} catch (Mailbox::Overflow) {
if (verbose)
Genode::warning(__func__, ": overflow exception!");
} catch (...) {
Genode::error(__func__, ": unknown exception occured!");
}
return ERR_MEM;
}
/**
* Fetch a "msg" from the mailbox.
*
* \param mbox target mailbox
* \param msg pointer to message buffer
* \param timeout how long will it block, if no message is available
*/
u32_t sys_arch_mbox_fetch(sys_mbox_t* mbox, void **msg, u32_t timeout)
{
/*
* The mailbox might be invalid to indicate,
* that the message should be dropped
*/
if (!mbox)
return 0;
u32_t ret = 0;
try {
Mailbox* _mbox = reinterpret_cast<Mailbox *>(mbox->ptr);
if (!_mbox)
return 0;
ret = _mbox->get(msg, timeout);
} catch (Genode::Timeout_exception) {
ret = SYS_ARCH_TIMEOUT;
} catch (Genode::Nonblocking_exception) {
ret = SYS_MBOX_EMPTY;
} catch (...) {
Genode::error(__func__, ": unknown exception occured!");
ret = SYS_ARCH_TIMEOUT;
}
return ret;
}
/**
* Try to fetch a "msg" from the mailbox.
*
* \param mbox target mailbox
* \param msg pointer to message buffer
* \return on success 0 is returned.
*
* 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.
*/
u32_t sys_arch_mbox_tryfetch(sys_mbox_t* mbox, void **msg)
{
return sys_arch_mbox_fetch(mbox, msg, Mailbox::NO_BLOCK);
}
/*************
** Threads **
*************/
/**
* Create and run a new thread.
*
* \param name name of the new thread
* \param thread pointer to thread's entry function
* \param arg arguments to the entry function
* \param stacksize size of the thread's stack
* \param prio priority of new thread
*/
sys_thread_t sys_thread_new(const char *name, void (* thread)(void *arg),
void *arg, int stacksize, int prio)
{
try
{
LWIP_UNUSED_ARG(stacksize);
LWIP_UNUSED_ARG(prio);
Lwip_thread *_th = new (Genode::env()->heap())
Lwip_thread(name, thread, arg);
_th->start();
return (sys_thread_t) _th;
} catch (Genode::Allocator::Out_of_memory) {
Genode::warning(__func__, ": out of memory");
return 0;
} catch (...) {
Genode::error(__func__, ": unknown Exception occured!");
return ERR_MEM;
}
}
u32_t sys_now() {
return Genode::Timeout_thread::alarm_timer()->time(); }
#if 0
/**************
** Timeouts **
**************/
/**
* Returns linked list of timeout for a thread created within LwIP
* (by now this is only the tcpip thread)
*/
struct sys_timeouts *sys_arch_timeouts(void)
{
using namespace Genode;
struct Thread_timeout
{
sys_timeouts timeouts;
Thread *thread;
Thread_timeout *next;
Thread_timeout(Thread *t = 0)
: thread(t), next(0) { timeouts.next = 0; }
};
static Lock mutex;
static Thread_timeout thread_timeouts;
Lock::Guard lock_guard(mutex);
try {
Thread *thread = Thread::myself();
/* check available timeout heads */
for (Thread_timeout *tt = &thread_timeouts; tt; tt = tt->next)
if (tt->thread == thread)
return &tt->timeouts;
/* we have to add a new one */
Thread_timeout *tt = new (env()->heap()) Thread_timeout(thread);
tt->next = thread_timeouts.next;
thread_timeouts.next = tt;
return &tt->timeouts;
} catch (...) {
Genode::error(__func__, ": unknown exception occured!");
return 0;
}
}
#endif
void genode_memcpy(void * dst, const void *src, unsigned long size) {
Genode::memcpy(dst, src, size);
}
} /* extern "C" */
extern "C" void lwip_sleep_forever()
{
int dummy = 1;
Genode::log(__func__, ": thread ", (unsigned)(((Genode::addr_t)&dummy)>>20)&0xff);
Genode::sleep_forever();
}

View File

@ -1,26 +0,0 @@
diff --git a/src/core/dhcp.c b/src/core/dhcp.c
index 21fd784..d85d86c 100644
--- a/src/core/dhcp.c
+++ b/src/core/dhcp.c
@@ -982,7 +982,7 @@ dhcp_bind(struct netif *netif)
ip_addr_copy(gw_addr, dhcp->offered_gw_addr);
/* gateway address not given? */
- if (ip_addr_isany(&gw_addr)) {
+ if (gw_addr.addr == IPADDR_ANY) {
/* copy network address */
ip_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask);
/* use first host address on network as gateway */
diff --git a/src/include/ipv4/lwip/ip4_addr.h b/src/include/ipv4/lwip/ip4_addr.h
index b05ae53..dc0d9a8 100644
--- a/src/include/ipv4/lwip/ip4_addr.h
+++ b/src/include/ipv4/lwip/ip4_addr.h
@@ -210,7 +210,7 @@ u8_t ip4_addr_netmask_valid(u32_t netmask);
#define ip_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL))
#define ip_addr_debug_print(debug, ipaddr) \
- LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \
+ LWIP_DEBUGF(debug, ("%" U16_F ".%" U16_F ".%" U16_F ".%" U16_F, \
ipaddr != NULL ? ip4_addr1_16(ipaddr) : 0, \
ipaddr != NULL ? ip4_addr2_16(ipaddr) : 0, \
ipaddr != NULL ? ip4_addr3_16(ipaddr) : 0, \

View File

@ -1,16 +0,0 @@
This patch is necessary because lwip always returns EALREADY if the
connection is established but never EISCONN. So most programs will
fail to connect because they at one point while connecting expect to
get EISCONN.
--- a/src/api/sockets.c
+++ b/src/api/sockets.c
@@ -214,7 +214,7 @@ static const int err_to_errno_table[] = {
EINVAL, /* ERR_VAL -6 Illegal value. */
EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
EADDRINUSE, /* ERR_USE -8 Address in use. */
- EALREADY, /* ERR_ISCONN -9 Already connected. */
+ EISCONN, /* ERR_ISCONN -9 Already connected. */
ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */
ECONNRESET, /* ERR_RST -11 Connection reset. */
ENOTCONN, /* ERR_CLSD -12 Connection closed. */

View File

@ -1,15 +0,0 @@
Our FreeBSD libc based libc defines SOL_SOCKET as 0xffff. We change
lwip's definition from 0xfff to match ours. This prevents us from
converting the level when we call {g,s}etsockopt.
--- a/src/include/lwip/sockets.h
+++ b/src/include/lwip/sockets.h
@@ -131,7 +131,7 @@ struct linger {
/*
* Level number for (get/set)sockopt() to apply to socket itself.
*/
-#define SOL_SOCKET 0xfff /* options for socket level */
+#define SOL_SOCKET 0xffff /* options for socket level */
#define AF_UNSPEC 0

View File

@ -1,12 +0,0 @@
{
global:
lwip_*;
ipaddr_addr;
dns_getserver;
ipaddr_ntoa;
local:
*;
};

View File

@ -21,8 +21,9 @@ virtual network between the lighttpd web server and the Arora web browser, both
running as Genode processes without real network connectivity. running as Genode processes without real network connectivity.
The static IP can be configured per client of the NIC bridge using a '<policy>' The static IP can be configured per client of the NIC bridge using a '<policy>'
node of the configuration. For example, the following policy assigns a static node of the configuration. Of course, the client needs to configure its TCP/IP
address to a client with the session label "lighttpd". stack to use the assigned IP address. As an example, the following policy assigns
a static address to a client with the session label "lighttpd".
!<start name="nic_bridge"> !<start name="nic_bridge">
! ... ! ...
@ -31,18 +32,6 @@ address to a client with the session label "lighttpd".
! </config> ! </config>
!</start> !</start>
Of course, the client needs to configure its TCP/IP stack to use the assigned
IP address. This can be done via configuration arguments examined by the
'lwip_nic_dhcp' libc plugin. For the given example, the configuration for the
lighttpd process would look as follows.
!<start name="lighttpd">
! <config>
! <interface ip_addr="10.0.2.55"
! netmask="255.255.255.0"
! gateway="10.0.2.1"/>
! </config>
!</start>
The verbosity mode of the NIC bridge can be toggled with the verbose attribute The verbosity mode of the NIC bridge can be toggled with the verbose attribute
(default value shown): (default value shown):

View File

@ -18,6 +18,7 @@ set build_components {
core init core init
drivers/timer drivers/timer
app/lighttpd app/lighttpd
lib/vfs/lwip
} }
set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi]] set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi]]
@ -102,9 +103,12 @@ append config {
<log/> <log/>
<null/> <null/>
</dir> </dir>
<dir name="socket">
<lwip dhcp="yes"/> </dir>
<tar name="genode_org.tar"/> <tar name="genode_org.tar"/>
</vfs> </vfs>
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"/> <libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"
socket="/socket" />
</config> </config>
</start>} </start>}
@ -160,8 +164,8 @@ exec tar cfv bin/genode_org.tar -h -C bin/genode_org .
# generic modules # generic modules
set boot_modules { set boot_modules {
core init timer ld.lib.so core init timer ld.lib.so
libc.lib.so vfs.lib.so libm.lib.so posix.lib.so libc.lib.so libm.lib.so posix.lib.so
lwip_legacy.lib.so zlib.lib.so vfs.lib.so vfs_lwip.lib.so zlib.lib.so
lighttpd genode_org.tar lighttpd genode_org.tar
} }

View File

@ -59,6 +59,8 @@ append config {
<log/> <log/>
<null/> <null/>
</dir> </dir>
<dir name="socket">
<lwip dhcp="yes"/> </dir>
<dir name="etc"> <dir name="etc">
<dir name="lighttpd"> <dir name="lighttpd">
<inline name="lighttpd.conf"> <inline name="lighttpd.conf">
@ -91,7 +93,8 @@ mimetype.assign = (
</inline> </inline>
</dir> </dir>
</vfs> </vfs>
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"/> <libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"
socket="/socket" />
</config> </config>
</start>} </start>}
@ -108,8 +111,8 @@ install_config $config
# generic modules # generic modules
append boot_modules { append boot_modules {
core init timer ld.lib.so } [nic_drv_binary] { core init timer ld.lib.so } [nic_drv_binary] {
libc.lib.so vfs.lib.so libm.lib.so posix.lib.so libc.lib.so libm.lib.so posix.lib.so
lwip_legacy.lib.so zlib.lib.so vfs.lib.so vfs_lwip.lib.so zlib.lib.so
lighttpd lighttpd
} }

View File

@ -106,6 +106,7 @@ set build_components {
server/ram_fs server/report_rom server/ram_fs server/report_rom
server/tcp_terminal drivers/nic server/tcp_terminal drivers/nic
lib/libc_noux lib/libc_noux
lib/vfs/lwip
noux noux
} }
@ -118,7 +119,7 @@ foreach pkg {bash coreutils} {
set boot_modules { set boot_modules {
ram_fs ram_fs
noux libc_noux.lib.so posix.lib.so bash.tar coreutils.tar noux libc_noux.lib.so posix.lib.so bash.tar coreutils.tar
tcp_terminal lwip_legacy.lib.so nic_drv report_rom tcp_terminal vfs_lwip.lib.so nic_drv report_rom
input_merger input_merger
test.bin template.bat test.bin template.bat
} }
@ -136,8 +137,11 @@ set config_of_app {
<provides> <service name="Terminal"/> </provides> <provides> <service name="Terminal"/> </provides>
<config> <config>
<policy label_prefix="noux" port="8888"/> <policy label_prefix="noux" port="8888"/>
<vfs> <dir name="dev"> <log/> </dir> </vfs> <vfs>
<libc stdout="/dev/log"/> <dir name="dev"> <log/> </dir>
<dir name="socket"> <lwip dhcp="yes"/> </dir>
</vfs>
<libc stdout="/dev/log" socket="/socket" />
</config> </config>
</start> </start>

View File

@ -2,6 +2,6 @@ TARGET = lighttpd
include $(REP_DIR)/src/app/lighttpd/target.inc include $(REP_DIR)/src/app/lighttpd/target.inc
LIBS += libc libm libc_lwip_nic_dhcp LIBS += libc libm
CC_CXX_WARN_STRICT = CC_CXX_WARN_STRICT =

View File

@ -1,7 +1,6 @@
TARGET = openvpn TARGET = openvpn
LIBS += libc libc_pipe libc_lwip_nic_dhcp \ LIBS += libc libc_pipe libcrypto libssl
libcrypto libssl
OPENVPN_PORT_DIR := $(call select_from_ports,openvpn) OPENVPN_PORT_DIR := $(call select_from_ports,openvpn)
OPENVPN_DIR := $(OPENVPN_PORT_DIR)/src/app/openvpn OPENVPN_DIR := $(OPENVPN_PORT_DIR)/src/app/openvpn