mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
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:
parent
1370fa7631
commit
fcbe060096
@ -13,6 +13,7 @@ set build_components {
|
||||
drivers/timer drivers/usb
|
||||
server/tcp_terminal
|
||||
test/terminal_echo
|
||||
lib/vfs/lwip
|
||||
}
|
||||
|
||||
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>
|
||||
<config>
|
||||
<policy label_prefix="test-terminal_echo" port="8888"/>
|
||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
||||
<libc stdout="/dev/log"/>
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> </dir>
|
||||
<dir name="socket"> <lwip dhcp="yes"/> </dir>
|
||||
</vfs>
|
||||
<libc stdout="/dev/log" socket="/socket"/>
|
||||
</config>
|
||||
<route>
|
||||
<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
|
||||
tcp_terminal
|
||||
test-terminal_echo
|
||||
vfs_lwip.lib.so
|
||||
}
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
@ -48,7 +48,7 @@ append config {
|
||||
<provides> <service name="Terminal"/> </provides>
|
||||
<config ld_verbose="yes">
|
||||
<policy label="test-terminal_echo" port="8888"/>
|
||||
<libc stdout="/dev/log">
|
||||
<libc stdout="/dev/log" socket="/socket"/>
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> </dir>
|
||||
<dir name="socket">
|
||||
|
@ -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
|
@ -20,6 +20,7 @@ set build_components {
|
||||
drivers/timer drivers/nic
|
||||
server/tcp_terminal
|
||||
test/terminal_echo
|
||||
lib/vfs/lwip
|
||||
}
|
||||
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
@ -58,12 +59,15 @@ set config {
|
||||
<provides> <service name="Nic"/> </provides>
|
||||
</start>
|
||||
<start name="tcp_terminal" caps="200">
|
||||
<resource name="RAM" quantum="2560K"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides> <service name="Terminal"/> </provides>
|
||||
<config>
|
||||
<policy label_prefix="test-terminal_echo" port="8888"/>
|
||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
||||
<libc stdout="/dev/log"/>
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> </dir>
|
||||
<dir name="socket"> <lwip dhcp="yes"/> </dir>
|
||||
</vfs>
|
||||
<libc stdout="/dev/log" socket="/socket"/>
|
||||
</config>
|
||||
</start>
|
||||
<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
|
||||
tcp_terminal
|
||||
test-terminal_echo
|
||||
vfs_lwip.lib.so
|
||||
}
|
||||
|
||||
# platform-specific modules
|
||||
|
@ -14,8 +14,6 @@
|
||||
#include <base/child.h>
|
||||
#include <base/log.h>
|
||||
#include <base/sleep.h>
|
||||
#include <lwip_legacy/genode.h>
|
||||
#include <nic/packet_allocator.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -1,6 +1,5 @@
|
||||
TARGET = http_blk
|
||||
SRC_CC = main.cc http.cc
|
||||
LIBS = libc libc_lwip_nic_dhcp
|
||||
|
||||
LIBS = libc
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
||||
|
@ -1,5 +1,5 @@
|
||||
TARGET = tcp_terminal
|
||||
SRC_CC = main.cc
|
||||
LIBS = libc pthread libc_lwip_nic_dhcp libc_pipe
|
||||
LIBS = libc pthread libc_pipe
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
||||
|
@ -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__ */
|
@ -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__ */
|
@ -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__ */
|
@ -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__ */
|
@ -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__ */
|
@ -1,2 +0,0 @@
|
||||
INC_DIR += $(call select_from_ports,lwip_legacy)/include/lwip_legacy
|
||||
INC_DIR += $(call select_from_repositories,include/lwip_legacy)
|
@ -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 =
|
@ -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 =
|
@ -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 =
|
@ -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 =
|
@ -1 +0,0 @@
|
||||
7f5610426ed8c4c64903136122d9ba58836cdc89
|
@ -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
|
@ -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();
|
||||
}
|
@ -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;
|
||||
}
|
@ -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();
|
||||
*/
|
||||
}
|
@ -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;
|
||||
}
|
@ -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)
|
@ -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
|
@ -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_
|
@ -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_
|
@ -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__
|
@ -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_
|
@ -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.
|
@ -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);
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
@ -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, \
|
@ -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. */
|
@ -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
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
global:
|
||||
|
||||
lwip_*;
|
||||
ipaddr_addr;
|
||||
dns_getserver;
|
||||
ipaddr_ntoa;
|
||||
|
||||
local:
|
||||
|
||||
*;
|
||||
};
|
@ -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.
|
||||
|
||||
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
|
||||
address to a client with the session label "lighttpd".
|
||||
node of the configuration. Of course, the client needs to configure its TCP/IP
|
||||
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">
|
||||
! ...
|
||||
@ -31,18 +32,6 @@ address to a client with the session label "lighttpd".
|
||||
! </config>
|
||||
!</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
|
||||
(default value shown):
|
||||
|
@ -18,6 +18,7 @@ set build_components {
|
||||
core init
|
||||
drivers/timer
|
||||
app/lighttpd
|
||||
lib/vfs/lwip
|
||||
}
|
||||
|
||||
set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi]]
|
||||
@ -102,9 +103,12 @@ append config {
|
||||
<log/>
|
||||
<null/>
|
||||
</dir>
|
||||
<dir name="socket">
|
||||
<lwip dhcp="yes"/> </dir>
|
||||
<tar name="genode_org.tar"/>
|
||||
</vfs>
|
||||
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"/>
|
||||
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"
|
||||
socket="/socket" />
|
||||
</config>
|
||||
</start>}
|
||||
|
||||
@ -160,8 +164,8 @@ exec tar cfv bin/genode_org.tar -h -C bin/genode_org .
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core init timer ld.lib.so
|
||||
libc.lib.so vfs.lib.so libm.lib.so posix.lib.so
|
||||
lwip_legacy.lib.so zlib.lib.so
|
||||
libc.lib.so libm.lib.so posix.lib.so
|
||||
vfs.lib.so vfs_lwip.lib.so zlib.lib.so
|
||||
lighttpd genode_org.tar
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,8 @@ append config {
|
||||
<log/>
|
||||
<null/>
|
||||
</dir>
|
||||
<dir name="socket">
|
||||
<lwip dhcp="yes"/> </dir>
|
||||
<dir name="etc">
|
||||
<dir name="lighttpd">
|
||||
<inline name="lighttpd.conf">
|
||||
@ -91,7 +93,8 @@ mimetype.assign = (
|
||||
</inline>
|
||||
</dir>
|
||||
</vfs>
|
||||
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"/>
|
||||
<libc stdin="/dev/null" stdout="/dev/log" stderr="/dev/log"
|
||||
socket="/socket" />
|
||||
</config>
|
||||
</start>}
|
||||
|
||||
@ -108,8 +111,8 @@ install_config $config
|
||||
# generic modules
|
||||
append boot_modules {
|
||||
core init timer ld.lib.so } [nic_drv_binary] {
|
||||
libc.lib.so vfs.lib.so libm.lib.so posix.lib.so
|
||||
lwip_legacy.lib.so zlib.lib.so
|
||||
libc.lib.so libm.lib.so posix.lib.so
|
||||
vfs.lib.so vfs_lwip.lib.so zlib.lib.so
|
||||
lighttpd
|
||||
}
|
||||
|
||||
|
@ -106,6 +106,7 @@ set build_components {
|
||||
server/ram_fs server/report_rom
|
||||
server/tcp_terminal drivers/nic
|
||||
lib/libc_noux
|
||||
lib/vfs/lwip
|
||||
noux
|
||||
}
|
||||
|
||||
@ -118,7 +119,7 @@ foreach pkg {bash coreutils} {
|
||||
set boot_modules {
|
||||
ram_fs
|
||||
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
|
||||
test.bin template.bat
|
||||
}
|
||||
@ -136,8 +137,11 @@ set config_of_app {
|
||||
<provides> <service name="Terminal"/> </provides>
|
||||
<config>
|
||||
<policy label_prefix="noux" port="8888"/>
|
||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
||||
<libc stdout="/dev/log"/>
|
||||
<vfs>
|
||||
<dir name="dev"> <log/> </dir>
|
||||
<dir name="socket"> <lwip dhcp="yes"/> </dir>
|
||||
</vfs>
|
||||
<libc stdout="/dev/log" socket="/socket" />
|
||||
</config>
|
||||
</start>
|
||||
|
||||
|
@ -2,6 +2,6 @@ TARGET = lighttpd
|
||||
|
||||
include $(REP_DIR)/src/app/lighttpd/target.inc
|
||||
|
||||
LIBS += libc libm libc_lwip_nic_dhcp
|
||||
LIBS += libc libm
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
||||
|
@ -1,7 +1,6 @@
|
||||
TARGET = openvpn
|
||||
|
||||
LIBS += libc libc_pipe libc_lwip_nic_dhcp \
|
||||
libcrypto libssl
|
||||
LIBS += libc libc_pipe libcrypto libssl
|
||||
|
||||
OPENVPN_PORT_DIR := $(call select_from_ports,openvpn)
|
||||
OPENVPN_DIR := $(OPENVPN_PORT_DIR)/src/app/openvpn
|
||||
|
Loading…
Reference in New Issue
Block a user