lxip: Port of the Linux TCP/IP stack
parent
864a047206
commit
5e17fef898
@ -0,0 +1,228 @@
|
||||
linux-3.9/include/asm-generic/bitops/__ffs.h
|
||||
linux-3.9/include/asm-generic/bitops/non-atomic.h
|
||||
linux-3.9/include/asm-generic/ioctl.h
|
||||
linux-3.9/include/linux/byteorder/generic.h
|
||||
linux-3.9/include/linux/hiddev.h
|
||||
linux-3.9/include/linux/hid.h
|
||||
linux-3.9/include/linux/input.h
|
||||
linux-3.9/include/linux/input/mt.h
|
||||
linux-3.9/include/linux/list.h
|
||||
linux-3.9/include/linux/mod_devicetable.h
|
||||
linux-3.9/include/linux/netdev_features.h
|
||||
linux-3.9/include/linux/pci_ids.h
|
||||
linux-3.9/include/linux/platform_data/dwc3-exynos.h
|
||||
linux-3.9/include/linux/platform_data/usb-ehci-s5p.h
|
||||
linux-3.9/include/linux/platform_data/usb-omap.h
|
||||
linux-3.9/include/linux/swab.h
|
||||
linux-3.9/include/linux/usb/ch9.h
|
||||
linux-3.9/include/linux/usb/ehci_def.h
|
||||
linux-3.9/include/linux/usb.h
|
||||
linux-3.9/include/linux/usb/hcd.h
|
||||
linux-3.9/include/linux/usb/input.h
|
||||
linux-3.9/include/linux/usb/otg.h
|
||||
linux-3.9/include/linux/usb/phy.h
|
||||
linux-3.9/include/linux/usb/quirks.h
|
||||
linux-3.9/include/linux/usb/storage.h
|
||||
linux-3.9/include/linux/usb/usbnet.h
|
||||
linux-3.9/include/linux/usb_usual.h
|
||||
linux-3.9/include/scsi/scsi.h
|
||||
linux-3.9/include/scsi/scsi_host.h
|
||||
linux-3.9/include/uapi/asm-generic/ioctl.h
|
||||
linux-3.9/include/uapi/linux/byteorder/little_endian.h
|
||||
linux-3.9/include/uapi/linux/hid.h
|
||||
linux-3.9/include/uapi/linux/input.h
|
||||
linux-3.9/include/uapi/linux/pci_regs.h
|
||||
linux-3.9/include/uapi/linux/usb/ch11.h
|
||||
linux-3.9/include/uapi/linux/usb/ch9.h
|
||||
linux-3.9/arch/arm/plat-samsung/include/plat/usb-phy.h
|
||||
linux-3.9/drivers/hid/hid-cherry.c
|
||||
linux-3.9/drivers/hid/hid-core.c
|
||||
linux-3.9/drivers/hid/hid-generic.c
|
||||
linux-3.9/drivers/hid/hid-ids.h
|
||||
linux-3.9/drivers/hid/hid-input.c
|
||||
linux-3.9/drivers/hid/usbhid/hid-core.c
|
||||
linux-3.9/drivers/hid/usbhid/hiddev.c
|
||||
linux-3.9/drivers/hid/usbhid/hid-pidff.c
|
||||
linux-3.9/drivers/hid/usbhid/hid-quirks.c
|
||||
linux-3.9/drivers/hid/usbhid/Kconfig
|
||||
linux-3.9/drivers/hid/usbhid/Makefile
|
||||
linux-3.9/drivers/hid/usbhid/usbhid.h
|
||||
linux-3.9/drivers/hid/usbhid/usbkbd.c
|
||||
linux-3.9/drivers/hid/usbhid/usbmouse.c
|
||||
linux-3.9/drivers/input/evdev.c
|
||||
linux-3.9/drivers/input/input.c
|
||||
linux-3.9/drivers/input/input-compat.h
|
||||
linux-3.9/drivers/net/usb/asix_common.c
|
||||
linux-3.9/drivers/net/usb/asix_devices.c
|
||||
linux-3.9/drivers/net/usb/asix.h
|
||||
linux-3.9/drivers/net/usb/ax88172a.c
|
||||
linux-3.9/drivers/net/usb/ax88179_178a.c
|
||||
linux-3.9/drivers/net/usb/smsc95xx.c
|
||||
linux-3.9/drivers/net/usb/smsc95xx.h
|
||||
linux-3.9/drivers/net/usb/usbnet.c
|
||||
linux-3.9/drivers/scsi/constants.c
|
||||
linux-3.9/drivers/scsi/scsi.c
|
||||
linux-3.9/drivers/scsi/scsi.h
|
||||
linux-3.9/drivers/scsi/scsi_logging.h
|
||||
linux-3.9/drivers/scsi/scsi_priv.h
|
||||
linux-3.9/drivers/usb/core/buffer.c
|
||||
linux-3.9/drivers/usb/core/config.c
|
||||
linux-3.9/drivers/usb/core/devices.c
|
||||
linux-3.9/drivers/usb/core/driver.c
|
||||
linux-3.9/drivers/usb/core/endpoint.c
|
||||
linux-3.9/drivers/usb/core/file.c
|
||||
linux-3.9/drivers/usb/core/generic.c
|
||||
linux-3.9/drivers/usb/core/hcd.c
|
||||
linux-3.9/drivers/usb/core/hcd-pci.c
|
||||
linux-3.9/drivers/usb/core/hub.c
|
||||
linux-3.9/drivers/usb/core/hub.h
|
||||
linux-3.9/drivers/usb/core/message.c
|
||||
linux-3.9/drivers/usb/core/notify.c
|
||||
linux-3.9/drivers/usb/core/port.c
|
||||
linux-3.9/drivers/usb/core/quirks.c
|
||||
linux-3.9/drivers/usb/core/urb.c
|
||||
linux-3.9/drivers/usb/core/usb.c
|
||||
linux-3.9/drivers/usb/core/usb.h
|
||||
linux-3.9/drivers/usb/dwc3/core.c
|
||||
linux-3.9/drivers/usb/dwc3/core.h
|
||||
linux-3.9/drivers/usb/dwc3/debug.h
|
||||
linux-3.9/drivers/usb/dwc3/dwc3-exynos.c
|
||||
linux-3.9/drivers/usb/dwc3/gadget.h
|
||||
linux-3.9/drivers/usb/dwc3/host.c
|
||||
linux-3.9/drivers/usb/dwc3/io.h
|
||||
linux-3.9/drivers/usb/host/ehci-dbg.c
|
||||
linux-3.9/drivers/usb/host/ehci.h
|
||||
linux-3.9/drivers/usb/host/ehci-hcd.c
|
||||
linux-3.9/drivers/usb/host/ehci-hub.c
|
||||
linux-3.9/drivers/usb/host/ehci-mem.c
|
||||
linux-3.9/drivers/usb/host/ehci-omap.c
|
||||
linux-3.9/drivers/usb/host/ehci-pci.c
|
||||
linux-3.9/drivers/usb/host/ehci-q.c
|
||||
linux-3.9/drivers/usb/host/ehci-s5p.c
|
||||
linux-3.9/drivers/usb/host/ehci-sched.c
|
||||
linux-3.9/drivers/usb/host/ehci-sysfs.c
|
||||
linux-3.9/drivers/usb/host/ehci-timer.c
|
||||
linux-3.9/drivers/usb/host/ohci-dbg.c
|
||||
linux-3.9/drivers/usb/host/ohci.h
|
||||
linux-3.9/drivers/usb/host/ohci-hcd.c
|
||||
linux-3.9/drivers/usb/host/ohci-hub.c
|
||||
linux-3.9/drivers/usb/host/ohci-mem.c
|
||||
linux-3.9/drivers/usb/host/ohci-pci.c
|
||||
linux-3.9/drivers/usb/host/ohci-q.c
|
||||
linux-3.9/drivers/usb/host/pci-quirks.c
|
||||
linux-3.9/drivers/usb/host/pci-quirks.h
|
||||
linux-3.9/drivers/usb/host/uhci-debug.c
|
||||
linux-3.9/drivers/usb/host/uhci-hcd.c
|
||||
linux-3.9/drivers/usb/host/uhci-hcd.h
|
||||
linux-3.9/drivers/usb/host/uhci-hub.c
|
||||
linux-3.9/drivers/usb/host/uhci-pci.c
|
||||
linux-3.9/drivers/usb/host/uhci-q.c
|
||||
linux-3.9/drivers/usb/host/xhci.c
|
||||
linux-3.9/drivers/usb/host/xhci-dbg.c
|
||||
linux-3.9/drivers/usb/host/xhci-ext-caps.h
|
||||
linux-3.9/drivers/usb/host/xhci.h
|
||||
linux-3.9/drivers/usb/host/xhci-hub.c
|
||||
linux-3.9/drivers/usb/host/xhci-mem.c
|
||||
linux-3.9/drivers/usb/host/xhci-plat.c
|
||||
linux-3.9/drivers/usb/host/xhci-ring.c
|
||||
linux-3.9/drivers/usb/storage/alauda.c
|
||||
linux-3.9/drivers/usb/storage/cypress_atacb.c
|
||||
linux-3.9/drivers/usb/storage/datafab.c
|
||||
linux-3.9/drivers/usb/storage/debug.c
|
||||
linux-3.9/drivers/usb/storage/debug.h
|
||||
linux-3.9/drivers/usb/storage/ene_ub6250.c
|
||||
linux-3.9/drivers/usb/storage/freecom.c
|
||||
linux-3.9/drivers/usb/storage/initializers.c
|
||||
linux-3.9/drivers/usb/storage/initializers.h
|
||||
linux-3.9/drivers/usb/storage/isd200.c
|
||||
linux-3.9/drivers/usb/storage/jumpshot.c
|
||||
linux-3.9/drivers/usb/storage/karma.c
|
||||
linux-3.9/drivers/usb/storage/Kconfig
|
||||
linux-3.9/drivers/usb/storage/Makefile
|
||||
linux-3.9/drivers/usb/storage/onetouch.c
|
||||
linux-3.9/drivers/usb/storage/option_ms.c
|
||||
linux-3.9/drivers/usb/storage/option_ms.h
|
||||
linux-3.9/drivers/usb/storage/protocol.c
|
||||
linux-3.9/drivers/usb/storage/protocol.h
|
||||
linux-3.9/drivers/usb/storage/realtek_cr.c
|
||||
linux-3.9/drivers/usb/storage/scsiglue.c
|
||||
linux-3.9/drivers/usb/storage/scsiglue.h
|
||||
linux-3.9/drivers/usb/storage/sddr09.c
|
||||
linux-3.9/drivers/usb/storage/sddr55.c
|
||||
linux-3.9/drivers/usb/storage/shuttle_usbat.c
|
||||
linux-3.9/drivers/usb/storage/sierra_ms.c
|
||||
linux-3.9/drivers/usb/storage/sierra_ms.h
|
||||
linux-3.9/drivers/usb/storage/transport.c
|
||||
linux-3.9/drivers/usb/storage/transport.h
|
||||
linux-3.9/drivers/usb/storage/uas.c
|
||||
linux-3.9/drivers/usb/storage/unusual_alauda.h
|
||||
linux-3.9/drivers/usb/storage/unusual_cypress.h
|
||||
linux-3.9/drivers/usb/storage/unusual_datafab.h
|
||||
linux-3.9/drivers/usb/storage/unusual_devs.h
|
||||
linux-3.9/drivers/usb/storage/unusual_ene_ub6250.h
|
||||
linux-3.9/drivers/usb/storage/unusual_freecom.h
|
||||
linux-3.9/drivers/usb/storage/unusual_isd200.h
|
||||
linux-3.9/drivers/usb/storage/unusual_jumpshot.h
|
||||
linux-3.9/drivers/usb/storage/unusual_karma.h
|
||||
linux-3.9/drivers/usb/storage/unusual_onetouch.h
|
||||
linux-3.9/drivers/usb/storage/unusual_realtek.h
|
||||
linux-3.9/drivers/usb/storage/unusual_sddr09.h
|
||||
linux-3.9/drivers/usb/storage/unusual_sddr55.h
|
||||
linux-3.9/drivers/usb/storage/unusual_usbat.h
|
||||
linux-3.9/drivers/usb/storage/usb.c
|
||||
linux-3.9/drivers/usb/storage/usb.h
|
||||
linux-3.9/drivers/usb/storage/usual-tables.c
|
||||
linux-3.9/drivers/usb/usb-common.c
|
||||
linux-3.9/lib/checksum.c
|
||||
linux-3.9/net/802/p8023.c
|
||||
linux-3.9/net/core/datagram.c
|
||||
linux-3.9/net/core/dev.c
|
||||
linux-3.9/net/core/dev_addr_lists.c
|
||||
linux-3.9/net/core/dst.c
|
||||
linux-3.9/net/core/ethtool.c
|
||||
linux-3.9/net/core/iovec.c
|
||||
linux-3.9/net/core/neighbour.c
|
||||
linux-3.9/net/core/net-sysfs.h
|
||||
linux-3.9/net/core/request_sock.c
|
||||
linux-3.9/net/core/skbuff.c
|
||||
linux-3.9/net/core/sock.c
|
||||
linux-3.9/net/core/stream.c
|
||||
linux-3.9/net/core/utils.c
|
||||
linux-3.9/net/ethernet/eth.c
|
||||
linux-3.9/net/ipv4/af_inet.c
|
||||
linux-3.9/net/ipv4/arp.c
|
||||
linux-3.9/net/ipv4/devinet.c
|
||||
linux-3.9/net/ipv4/fib_frontend.c
|
||||
linux-3.9/net/ipv4/fib_lookup.h
|
||||
linux-3.9/net/ipv4/fib_semantics.c
|
||||
linux-3.9/net/ipv4/fib_trie.c
|
||||
linux-3.9/net/ipv4/icmp.c
|
||||
linux-3.9/net/ipv4/inet_connection_sock.c
|
||||
linux-3.9/net/ipv4/inet_fragment.c
|
||||
linux-3.9/net/ipv4/inet_hashtables.c
|
||||
linux-3.9/net/ipv4/inetpeer.c
|
||||
linux-3.9/net/ipv4/ipconfig.c
|
||||
linux-3.9/net/ipv4/ip_forward.c
|
||||
linux-3.9/net/ipv4/ip_fragment.c
|
||||
linux-3.9/net/ipv4/ip_input.c
|
||||
linux-3.9/net/ipv4/ip_options.c
|
||||
linux-3.9/net/ipv4/ip_output.c
|
||||
linux-3.9/net/ipv4/ip_sockglue.c
|
||||
linux-3.9/net/ipv4/ping.c
|
||||
linux-3.9/net/ipv4/protocol.c
|
||||
linux-3.9/net/ipv4/raw.c
|
||||
linux-3.9/net/ipv4/route.c
|
||||
linux-3.9/net/ipv4/tcp.c
|
||||
linux-3.9/net/ipv4/tcp_cong.c
|
||||
linux-3.9/net/ipv4/tcp_cubic.c
|
||||
linux-3.9/net/ipv4/tcp_diag.c
|
||||
linux-3.9/net/ipv4/tcp_input.c
|
||||
linux-3.9/net/ipv4/tcp_ipv4.c
|
||||
linux-3.9/net/ipv4/tcp_minisocks.c
|
||||
linux-3.9/net/ipv4/tcp_output.c
|
||||
linux-3.9/net/ipv4/tcp_timer.c
|
||||
linux-3.9/net/ipv4/udp.c
|
||||
linux-3.9/net/ipv4/udp_impl.h
|
||||
linux-3.9/net/netlink/af_netlink.c
|
||||
linux-3.9/net/sched/sch_generic.c
|
||||
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* \brief Lxip: Linux TCP/IP as a library
|
||||
* \author Christian Helmuth
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2013-09-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_LXIP_LXIP_H_
|
||||
#define _INCLUDE_LXIP_LXIP_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Lxip {
|
||||
|
||||
struct Handle
|
||||
{
|
||||
void *socket;
|
||||
bool non_block;
|
||||
|
||||
Handle() : socket(0), non_block(false) { }
|
||||
};
|
||||
|
||||
enum Type { TYPE_STREAM, TYPE_DGRAM };
|
||||
|
||||
class Socketcall;
|
||||
|
||||
Socketcall & init();
|
||||
|
||||
typedef Genode::uint8_t uint8_t;
|
||||
typedef Genode::uint16_t uint16_t;
|
||||
typedef Genode::uint32_t uint32_t;
|
||||
typedef signed long ssize_t;
|
||||
typedef Genode::size_t size_t;
|
||||
|
||||
enum Poll_mask {
|
||||
POLLIN = 0x1,
|
||||
POLLOUT = 0x2,
|
||||
POLLEX = 0x4,
|
||||
};
|
||||
|
||||
enum Message_flags {
|
||||
LINUX_MSG_COMPAT = 0x0,
|
||||
LINUX_MSG_OOB = 0x1,
|
||||
LINUX_MSG_PEEK = 0x2,
|
||||
LINUX_MSG_DONTROUTE = 0x4,
|
||||
LINUX_MSG_CTRUNC = 0x8,
|
||||
LINUX_MSG_TRUNC = 0x20,
|
||||
LINUX_MSG_DONTWAIT = 0x40,
|
||||
LINUX_MSG_EOR = 0x80,
|
||||
LINUX_MSG_WAITALL = 0x100,
|
||||
LINUX_MSG_EOF = 0x200,
|
||||
LINUX_MSG_NOSIGNAL = 0x4000,
|
||||
};
|
||||
|
||||
enum Socket_level {
|
||||
LINUX_SOL_SOCKET = 1,
|
||||
};
|
||||
|
||||
enum Ioctl_cmd {
|
||||
LINUX_FIONREAD = 0x541b /* == SIOCINQ */
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
class Lxip::Socketcall
|
||||
{
|
||||
public:
|
||||
|
||||
virtual Handle accept(Handle h, void *addr, uint32_t *len) = 0;
|
||||
virtual int bind(Handle h, uint16_t family, void *addr) = 0;
|
||||
virtual void close(Handle h) = 0;
|
||||
virtual int connect(Handle h, uint16_t family, void *addr) = 0;
|
||||
virtual int getpeername(Handle h, void *addr, uint32_t *len) = 0;
|
||||
virtual int getsockname(Handle h, void *addr, uint32_t *len) = 0;
|
||||
virtual int getsockopt(Handle h, int level, int optname,
|
||||
void *optval, int *optlen) = 0;
|
||||
virtual int ioctl(Handle h, int request, char *arg) = 0;
|
||||
virtual int listen(Handle h, int backlog) = 0;
|
||||
virtual int poll(Handle h, bool block) = 0;
|
||||
virtual ssize_t recv(Handle h, void *buf, size_t len, int flags,
|
||||
uint16_t family, void *addr, uint32_t *addr_len) = 0;
|
||||
virtual ssize_t send(Handle h, const void *buf, size_t len, int flags,
|
||||
uint16_t family, void *addr) = 0;
|
||||
virtual int setsockopt(Handle h, int level, int optname,
|
||||
const void *optval, uint32_t optlen) = 0;
|
||||
virtual int shutdown(Handle h, int how) = 0;
|
||||
virtual Handle socket(Type) = 0;
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE_LXIP_LXIP_H_ */
|
@ -0,0 +1,5 @@
|
||||
SRC_CC = init.cc plugin.cc
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/lib/libc_lxip
|
||||
|
||||
LIBS += lxip libc libc_resolv
|
@ -0,0 +1,94 @@
|
||||
SHARED_LIB = yes
|
||||
|
||||
LIB_DIR = $(REP_DIR)/src/lib/lxip
|
||||
LIB_INC_DIR = $(LIB_DIR)/include
|
||||
|
||||
LIBS += base cxx dde_kit
|
||||
|
||||
CONTRIB_DIR := $(REP_DIR)/contrib
|
||||
NET_DIR := $(CONTRIB_DIR)/net
|
||||
|
||||
#
|
||||
# The order of include-search directories is important, we need to look into
|
||||
# 'contrib' before falling back to our custom 'lx_emul.h' header.
|
||||
#
|
||||
INC_DIR += $(LIB_INC_DIR)
|
||||
INC_DIR += $(CONTRIB_DIR)/include $(CONTRIB_DIR)/include/uapi \
|
||||
$(CONTRIB_DIR)/lxip/include $(CONTRIB_DIR)/lxip/include/uapi \
|
||||
$(CONTRIB_DIR)
|
||||
|
||||
CC_OLEVEL = -O2
|
||||
|
||||
SETUP_SUFFIX =
|
||||
CC_OPT += -DSETUP_SUFFIX=$(SETUP_SUFFIX)
|
||||
|
||||
CC_OPT += -U__linux__ -D__KERNEL__
|
||||
CC_OPT += -DCONFIG_INET -DCONFIG_BASE_SMALL=0 -DCONFIG_DEBUG_LOCK_ALLOC \
|
||||
-DCONFIG_IP_PNP_DHCP
|
||||
|
||||
CC_WARN = -Wall -Wno-unused-variable -Wno-uninitialized \
|
||||
-Wno-unused-function -Wno-overflow -Wno-pointer-arith \
|
||||
-Wno-sign-compare
|
||||
|
||||
CC_C_OPT += -Wno-implicit-function-declaration -Wno-unused-but-set-variable \
|
||||
-Wno-pointer-sign
|
||||
|
||||
CC_C_OPT += -include $(LIB_INC_DIR)/lx_emul.h
|
||||
CC_CXX_OPT = -fpermissive
|
||||
|
||||
SRC_CC = dummies.cc env.cc lxcc_emul.cc nic_handler.cc socket_handler.cc \
|
||||
timer_handler.cc
|
||||
|
||||
SRC_C += driver.c init.c lxc_emul.c socket.c
|
||||
|
||||
SRC_C += net/802/p8023.c
|
||||
SRC_C += $(addprefix net/core/,$(notdir $(wildcard $(NET_DIR)/core/*.c)))
|
||||
SRC_C += $(addprefix net/ipv4/,$(notdir $(wildcard $(NET_DIR)/ipv4/*.c)))
|
||||
SRC_C += net/ethernet/eth.c
|
||||
SRC_C += net/netlink/af_netlink.c
|
||||
SRC_C += net/sched/sch_generic.c
|
||||
SRC_C += lib/checksum.c
|
||||
|
||||
# DHCP support
|
||||
SRC_C += net/ipv4/ipconfig.c
|
||||
|
||||
#SRC_C = net/ipv4/inet_connection_sock.c
|
||||
|
||||
#
|
||||
# Determine the header files included by the contrib code. For each
|
||||
# of these header files we create a symlink to 'lx_emul.h'.
|
||||
#
|
||||
GEN_INCLUDES := $(shell grep -rh "^\#include .*\/" $(CONTRIB_DIR) |\
|
||||
sed "s/^\#include [^<\"]*[<\"]\([^>\"]*\)[>\"].*/\1/" | sort | uniq)
|
||||
|
||||
#
|
||||
# Filter out original Linux headers that exist in the contrib directory
|
||||
#
|
||||
NO_GEN_INCLUDES := $(shell cd $(CONTRIB_DIR); find -name "*.h" | sed "s/.\///" | sed "s/.*include\///")
|
||||
GEN_INCLUDES := $(filter-out $(NO_GEN_INCLUDES),$(GEN_INCLUDES))
|
||||
|
||||
#
|
||||
# Put Linux headers in 'GEN_INC' dir, since some include use "../../" paths use
|
||||
# three level include hierarchy
|
||||
#
|
||||
GEN_INC := $(shell pwd)/include/include/include
|
||||
|
||||
$(shell mkdir -p $(GEN_INC))
|
||||
|
||||
GEN_INCLUDES := $(addprefix $(GEN_INC)/,$(GEN_INCLUDES))
|
||||
INC_DIR += $(GEN_INC)
|
||||
|
||||
#
|
||||
# Make sure to create the header symlinks prior building
|
||||
#
|
||||
$(SRC_C:.c=.o) $(SRC_CC:.cc=.o): $(GEN_INCLUDES)
|
||||
|
||||
net/ethernet/eth.o: SETUP_SUFFIX="_eth"
|
||||
|
||||
$(GEN_INCLUDES):
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)ln -s $(LIB_INC_DIR)/lx_emul.h $@
|
||||
|
||||
vpath %.c $(CONTRIB_DIR)
|
||||
vpath %.c $(LIB_DIR)
|
||||
vpath %.cc $(LIB_DIR)
|
@ -0,0 +1,85 @@
|
||||
linux-3.9/include/linux/errqueue.h
|
||||
linux-3.9/include/linux/etherdevice.h
|
||||
linux-3.9/include/linux/ethtool.h
|
||||
linux-3.9/include/linux/icmp.h
|
||||
linux-3.9/include/linux/if_arp.h
|
||||
linux-3.9/include/linux/if_ether.h
|
||||
linux-3.9/include/linux/if_link.h
|
||||
linux-3.9/include/linux/jhash.h
|
||||
linux-3.9/include/linux/inetdevice.h
|
||||
linux-3.9/include/linux/list_nulls.h
|
||||
linux-3.9/include/linux/netdev_features.h
|
||||
linux-3.9/include/linux/netdevice.h
|
||||
linux-3.9/include/linux/net.h
|
||||
linux-3.9/include/linux/netlink.h
|
||||
linux-3.9/include/linux/skbuff.h
|
||||
linux-3.9/include/linux/socket.h
|
||||
linux-3.9/include/linux/tcp.h
|
||||
linux-3.9/include/linux/udp.h
|
||||
linux-3.9/include/net/arp.h
|
||||
linux-3.9/include/net/datalink.h
|
||||
linux-3.9/include/net/dst.h
|
||||
linux-3.9/include/net/dst_ops.h
|
||||
linux-3.9/include/net/dsfield.h
|
||||
linux-3.9/include/net/flow.h
|
||||
linux-3.9/include/net/icmp.h
|
||||
linux-3.9/include/net/inet_connection_sock.h
|
||||
linux-3.9/include/net/inet_frag.h
|
||||
linux-3.9/include/net/inet_hashtables.h
|
||||
linux-3.9/include/net/inetpeer.h
|
||||
linux-3.9/include/net/inet_sock.h
|
||||
linux-3.9/include/net/inet_timewait_sock.h
|
||||
linux-3.9/include/net/ipconfig.h
|
||||
linux-3.9/include/net/ip_fib.h
|
||||
linux-3.9/include/net/ip.h
|
||||
linux-3.9/include/net/neighbour.h
|
||||
linux-3.9/include/net/netlink.h
|
||||
linux-3.9/include/net/netns/ipv4.h
|
||||
linux-3.9/include/net/netns/mib.h
|
||||
linux-3.9/include/net/ping.h
|
||||
linux-3.9/include/net/pkt_sched.h
|
||||
linux-3.9/include/net/protocol.h
|
||||
linux-3.9/include/net/raw.h
|
||||
linux-3.9/include/net/request_sock.h
|
||||
linux-3.9/include/net/route.h
|
||||
linux-3.9/include/net/sch_generic.h
|
||||
linux-3.9/include/net/snmp.h
|
||||
linux-3.9/include/net/sock.h
|
||||
linux-3.9/include/net/tcp.h
|
||||
linux-3.9/include/net/tcp_states.h
|
||||
linux-3.9/include/net/timewait_sock.h
|
||||
linux-3.9/include/net/udp.h
|
||||
linux-3.9/include/net/udplite.h
|
||||
linux-3.9/include/uapi/asm-generic/socket.h
|
||||
linux-3.9/include/uapi/linux/errqueue.h
|
||||
linux-3.9/include/uapi/linux/ethtool.h
|
||||
linux-3.9/include/uapi/linux/fib_rules.h
|
||||
linux-3.9/include/uapi/linux/gen_stats.h
|
||||
linux-3.9/include/uapi/linux/icmp.h
|
||||
linux-3.9/include/uapi/linux/if_addr.h
|
||||
linux-3.9/include/uapi/linux/if_arp.h
|
||||
linux-3.9/include/uapi/linux/if_bridge.h
|
||||
linux-3.9/include/uapi/linux/if_ether.h
|
||||
linux-3.9/include/uapi/linux/if.h
|
||||
linux-3.9/include/uapi/linux/if_link.h
|
||||
linux-3.9/include/uapi/linux/if_packet.h
|
||||
linux-3.9/include/uapi/linux/in6.h
|
||||
linux-3.9/include/uapi/linux/inet_diag.h
|
||||
linux-3.9/include/uapi/linux/in.h
|
||||
linux-3.9/include/uapi/linux/in_route.h
|
||||
linux-3.9/include/uapi/linux/ip.h
|
||||
linux-3.9/include/uapi/linux/neighbour.h
|
||||
linux-3.9/include/uapi/linux/netconf.h
|
||||
linux-3.9/include/uapi/linux/netdevice.h
|
||||
linux-3.9/include/uapi/linux/netfilter.h
|
||||
linux-3.9/include/uapi/linux/net.h
|
||||
linux-3.9/include/uapi/linux/netlink.h
|
||||
linux-3.9/include/uapi/linux/pkt_sched.h
|
||||
linux-3.9/include/uapi/linux/route.h
|
||||
linux-3.9/include/uapi/linux/rtnetlink.h
|
||||
linux-3.9/include/uapi/linux/snmp.h
|
||||
linux-3.9/include/uapi/linux/socket.h
|
||||
linux-3.9/include/uapi/linux/sockios.h
|
||||
linux-3.9/include/uapi/linux/swab.h
|
||||
linux-3.9/include/uapi/linux/tcp.h
|
||||
linux-3.9/include/uapi/linux/udp.h
|
@ -0,0 +1,12 @@
|
||||
diff -r a4522abad72d net/ipv4/icmp.c
|
||||
--- a/net/ipv4/icmp.c Tue Oct 15 12:18:08 2013 +0200
|
||||
+++ b/net/ipv4/icmp.c Tue Oct 15 12:18:33 2013 +0200
|
||||
@@ -787,7 +787,7 @@
|
||||
if (!net->ipv4.sysctl_icmp_echo_ignore_all) {
|
||||
struct icmp_bxm icmp_param;
|
||||
|
||||
- icmp_param.data.icmph = *icmp_hdr(skb);
|
||||
+ memcpy(&icmp_param.data.icmph, icmp_hdr(skb), sizeof(struct icmphdr));
|
||||
icmp_param.data.icmph.type = ICMP_ECHOREPLY;
|
||||
icmp_param.skb = skb;
|
||||
icmp_param.offset = 0;
|
@ -0,0 +1,36 @@
|
||||
diff -r d3a8e67b38cf net/ipv4/ipconfig.c
|
||||
--- a/net/ipv4/ipconfig.c Fri Sep 20 12:18:22 2013 +0200
|
||||
+++ b/net/ipv4/ipconfig.c Fri Sep 20 12:18:56 2013 +0200
|
||||
@@ -1505,24 +1505,24 @@
|
||||
*/
|
||||
pr_info("IP-Config: Complete:\n");
|
||||
|
||||
- pr_info(" device=%s, hwaddr=%*phC, ipaddr=%pI4, mask=%pI4, gw=%pI4\n",
|
||||
- ic_dev->name, ic_dev->addr_len, ic_dev->dev_addr,
|
||||
- &ic_myaddr, &ic_netmask, &ic_gateway);
|
||||
+ pr_info(" device=%s, len=%u hwaddr=" MAC_FMT ", ipaddr=" IP_FMT ", mask=" IP_FMT " , gw=" IP_FMT "\n",
|
||||
+ ic_dev->name, ic_dev->addr_len, MAC_ARG(ic_dev->dev_addr),
|
||||
+ IP_ARG(ic_myaddr), IP_ARG(ic_netmask), IP_ARG(ic_gateway));
|
||||
pr_info(" host=%s, domain=%s, nis-domain=%s\n",
|
||||
utsname()->nodename, ic_domain, utsname()->domainname);
|
||||
- pr_info(" bootserver=%pI4, rootserver=%pI4, rootpath=%s",
|
||||
- &ic_servaddr, &root_server_addr, root_server_path);
|
||||
+ pr_info(" bootserver=" IP_FMT ", rootserver=" IP_FMT ", rootpath=%s\n",
|
||||
+ IP_ARG(ic_servaddr), IP_ARG(root_server_addr), root_server_path);
|
||||
if (ic_dev_mtu)
|
||||
pr_cont(", mtu=%d", ic_dev_mtu);
|
||||
for (i = 0; i < CONF_NAMESERVERS_MAX; i++)
|
||||
if (ic_nameservers[i] != NONE) {
|
||||
- pr_info(" nameserver%u=%pI4",
|
||||
- i, &ic_nameservers[i]);
|
||||
+ pr_info(" nameserver%u=" IP_FMT,
|
||||
+ i, IP_ARG(ic_nameservers[i]));
|
||||
break;
|
||||
}
|
||||
for (i++; i < CONF_NAMESERVERS_MAX; i++)
|
||||
if (ic_nameservers[i] != NONE)
|
||||
- pr_cont(", nameserver%u=%pI4", i, &ic_nameservers[i]);
|
||||
+ pr_cont(", nameserver%u=" IP_FMT, i, IP_ARG(ic_nameservers[i]));
|
||||
pr_cont("\n");
|
||||
#endif /* !SILENT */
|
||||
|
@ -0,0 +1,30 @@
|
||||
diff -r 6e1a0ab143a5 net/core/skbuff.c
|
||||
--- a/net/core/skbuff.c Fri Oct 18 12:02:45 2013 +0200
|
||||
+++ b/net/core/skbuff.c Fri Oct 18 12:04:07 2013 +0200
|
||||
@@ -419,23 +419,9 @@
|
||||
unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) +
|
||||
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
||||
|
||||
- if (fragsz <= PAGE_SIZE && !(gfp_mask & (__GFP_WAIT | GFP_DMA))) {
|
||||
- void *data;
|
||||
-
|
||||
- if (sk_memalloc_socks())
|
||||
- gfp_mask |= __GFP_MEMALLOC;
|
||||
-
|
||||
- data = __netdev_alloc_frag(fragsz, gfp_mask);
|
||||
-
|
||||
- if (likely(data)) {
|
||||
- skb = build_skb(data, fragsz);
|
||||
- if (unlikely(!skb))
|
||||
- put_page(virt_to_head_page(data));
|
||||
- }
|
||||
- } else {
|
||||
- skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask,
|
||||
- SKB_ALLOC_RX, NUMA_NO_NODE);
|
||||
- }
|
||||
+ skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask,
|
||||
+ SKB_ALLOC_RX, NUMA_NO_NODE);
|
||||
+
|
||||
if (likely(skb)) {
|
||||
skb_reserve(skb, NET_SKB_PAD);
|
||||
skb->dev = dev;
|
@ -0,0 +1,32 @@
|
||||
From 8b2f74f2258b62ca0e62656cdccbc9159aeab893 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
Date: Tue, 6 Aug 2013 16:12:54 +0200
|
||||
Subject: [PATCH] L4Linux: Increase TCP-window size
|
||||
|
||||
TCP window size is calculated by the amount of memory within L4Linux, use a
|
||||
larger window size to allow acceptable performance even on smaller VMs.
|
||||
---
|
||||
net/ipv4/tcp.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
|
||||
index e220207..29613bf 100644
|
||||
--- a/net/ipv4/tcp.c
|
||||
+++ b/net/ipv4/tcp.c
|
||||
@@ -3648,6 +3648,13 @@ void __init tcp_init(void)
|
||||
tcp_init_mem(&init_net);
|
||||
/* Set per-socket limits to no more than 1/128 the pressure threshold */
|
||||
limit = nr_free_buffer_pages() << (PAGE_SHIFT - 7);
|
||||
+
|
||||
+ /*
|
||||
+ * Adjust limit so it performs well on systems with little memory. If
|
||||
+ * this causes errors increase L4Linux main memory
|
||||
+ */
|
||||
+ limit = limit < 1024U * 1024 ? 1024U * 1024 : limit;
|
||||
+
|
||||
max_wshare = min(4UL*1024*1024, limit);
|
||||
max_rshare = min(6UL*1024*1024, limit);
|
||||
|
||||
--
|
||||
1.8.4
|
||||
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* \brief Lxip plugin creation
|
||||
* \author Christian Helmuth
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2013-09-04
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/printf.h>
|
||||
|
||||
extern void create_lxip_plugin();
|
||||
|
||||
void __attribute__((constructor)) init_libc_lxip(void)
|
||||
{
|
||||
PDBG("init_libc_lxip()\n");
|
||||
create_lxip_plugin();
|
||||
}
|
@ -0,0 +1,657 @@
|
||||
/*
|
||||
* \brief Lxip plugin implementation
|
||||
* \author Sebastian Sumpf
|
||||
* \author Christian Helmuth
|
||||
* \date 2013-09-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Libc includes */
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
/* Libc plugin includes */
|
||||
#include <libc-plugin/fd_alloc.h>
|
||||
#include <libc-plugin/plugin_registry.h>
|
||||
|
||||
/* Lxip includes */
|
||||
#include <lxip/lxip.h>
|
||||
|
||||
|
||||
/**************************
|
||||
** Linux family numbers **
|
||||
**************************/
|
||||
|
||||
enum {
|
||||
LINUX_AF_INET = 2
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
** Plugin interface **
|
||||
**********************/
|
||||
|
||||
extern "C" void wait_for_continue();
|
||||
|
||||
namespace {
|
||||
|
||||
class Plugin_context : public Libc::Plugin_context
|
||||
{
|
||||
private:
|
||||
|
||||
Lxip::Handle _handle;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Plugin_context(Lxip::Handle handle) : _handle(handle) { }
|
||||
|
||||
Lxip::Handle handle() const { return _handle; }
|
||||
|
||||
void non_block(bool nb) { _handle.non_block = nb; }
|
||||
};
|
||||
|
||||
|
||||
static inline Plugin_context * context(Libc::File_descriptor *fd)
|
||||
{
|
||||
return static_cast<Plugin_context *>(fd->context);
|
||||
}
|
||||
|
||||
|
||||
struct Plugin : Libc::Plugin
|
||||
{
|
||||
|
||||
/**
|
||||
* Interface to LXIP stack
|
||||
*/
|
||||
struct Lxip::Socketcall &socketcall;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Plugin();
|
||||
|
||||
bool supports_select(int nfds,
|
||||
fd_set *readfds,
|
||||
fd_set *writefds,
|
||||
fd_set *exceptfds,
|
||||
struct timeval *timeout);
|
||||
bool supports_socket(int domain, int type, int protocol);
|
||||
|
||||
Libc::File_descriptor *accept(Libc::File_descriptor *sockfdo,
|
||||
struct sockaddr *addr,
|
||||
socklen_t *addrlen);
|
||||
int bind(Libc::File_descriptor *sockfdo,
|
||||
const struct sockaddr *addr,
|
||||
socklen_t addrlen);
|
||||
int close(Libc::File_descriptor *fdo);
|
||||
int connect(Libc::File_descriptor *sockfdo,
|
||||
const struct sockaddr *addr,
|
||||
socklen_t addrlen);
|
||||
int fcntl(Libc::File_descriptor *sockfdo, int cmd, long val);
|
||||
int getpeername(Libc::File_descriptor *sockfdo,
|
||||
struct sockaddr *addr,
|
||||
socklen_t *addrlen);
|
||||
int getsockname(Libc::File_descriptor *sockfdo,
|
||||
struct sockaddr *addr,
|
||||
socklen_t *addrlen);
|
||||
int getsockopt(Libc::File_descriptor *sockfdo, int level,
|
||||
int optname, void *optval,
|
||||
socklen_t *optlen);
|
||||
int ioctl(Libc::File_descriptor *sockfdo, int request, char *argp);
|
||||
int listen(Libc::File_descriptor *sockfdo, int backlog);
|
||||
ssize_t read(Libc::File_descriptor *fdo, void *buf, ::size_t count);
|
||||
int shutdown(Libc::File_descriptor *fdo, int);
|
||||
int select(int nfds, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds, struct timeval *timeout);
|
||||
ssize_t send(Libc::File_descriptor *, const void *buf, ::size_t len, int flags);
|
||||
ssize_t sendto(Libc::File_descriptor *, const void *buf,
|
||||
::size_t len, int flags,
|
||||
const struct sockaddr *dest_addr,
|
||||
socklen_t addrlen);
|
||||
ssize_t recv(Libc::File_descriptor *, void *buf, ::size_t len, int flags);
|
||||
ssize_t recvfrom(Libc::File_descriptor *, void *buf, ::size_t len, int flags,
|
||||
struct sockaddr *src_addr, socklen_t *addrlen);
|
||||
int setsockopt(Libc::File_descriptor *sockfdo, int level,
|
||||
int optname, const void *optval,
|
||||
socklen_t optlen);
|
||||
Libc::File_descriptor *socket(int domain, int type, int protocol);
|
||||
ssize_t write(Libc::File_descriptor *fdo, const void *buf, ::size_t count);
|
||||
|
||||
int linux_family(const struct sockaddr *addr, socklen_t addrlen);
|
||||
int bsd_family(struct sockaddr *addr);
|
||||
int retrieve_and_clear_fds(int nfds, struct fd_set *fds, struct fd_set *in);
|
||||
int translate_msg_flags(int bsd_flags);
|
||||
int translate_ops_linux(int optname);
|
||||
};
|
||||
|
||||
|
||||
Plugin::Plugin() : socketcall(Lxip::init())
|
||||
{
|
||||
PDBG("using the lxip libc plugin");
|
||||
}
|
||||
|
||||
|
||||
/* TODO shameful copied from lwip... generalize this */
|
||||
bool Plugin::supports_select(int nfds,
|
||||
fd_set *readfds,
|
||||
fd_set *writefds,
|
||||
fd_set *exceptfds,
|
||||
struct timeval *timeout)
|
||||
{
|
||||
/*
|
||||
* Return true if any file descriptor which is marked set in one of
|
||||
* the sets belongs to this plugin.
|
||||
*/
|
||||
|
||||
Libc::File_descriptor *fdo;
|
||||
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 type, int)
|
||||
{
|
||||
if (domain == AF_INET && (type == SOCK_STREAM || type == SOCK_DGRAM))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Libc::File_descriptor *Plugin::accept(Libc::File_descriptor *sockfdo,
|
||||
struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
Lxip::Handle handle;
|
||||
|
||||
handle = socketcall.accept(context(sockfdo)->handle(), (void *)addr, addrlen);
|
||||
if (!handle.socket)
|
||||
return 0;
|
||||
|
||||
if (addr) {
|
||||
addr->sa_family = bsd_family(addr);
|
||||
addr->sa_len = *addrlen;
|
||||
}
|
||||
|
||||
Plugin_context *context = new (Genode::env()->heap()) Plugin_context(handle);
|
||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->alloc(this, context);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
int Plugin::bind(Libc::File_descriptor *sockfdo, const struct sockaddr *addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
int family;
|
||||
|
||||
if (!(family = linux_family(addr, addrlen))) {
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = -socketcall.bind(context(sockfdo)->handle(), family, (void*)addr);
|
||||
|
||||
return errno > 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
int Plugin::close(Libc::File_descriptor *sockfdo)
|
||||
{
|
||||
socketcall.close(context(sockfdo)->handle());
|
||||
|
||||
if (context(sockfdo))
|
||||
Genode::destroy(Genode::env()->heap(), context(sockfdo));
|
||||
|
||||
Libc::file_descriptor_allocator()->free(sockfdo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Plugin::connect(Libc::File_descriptor *sockfdo,
|
||||
const struct sockaddr *addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
int family;
|
||||
|
||||
if (!(family = linux_family(addr, addrlen))) {
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = -socketcall.connect(context(sockfdo)->handle(), family, (void *)addr);
|
||||
return errno > 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
int Plugin::fcntl(Libc::File_descriptor *sockfdo, int cmd, long val)
|
||||
{
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case F_GETFL:
|
||||
|
||||
return context(sockfdo)->handle().non_block ? O_NONBLOCK : 0;
|
||||
|
||||
case F_SETFL:
|
||||
|
||||
context(sockfdo)->non_block(!!(val & O_NONBLOCK));
|
||||
return 0;
|
||||
|
||||
default:
|
||||
|
||||
PERR("unsupported fcntl() request: %d", cmd);
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* XXX freeaddrinfo / getaddrinfo from libc_resolv.conf */
|
||||
int Plugin::getpeername(Libc::File_descriptor *sockfdo,
|
||||
struct sockaddr *addr,
|
||||
socklen_t *addrlen)
|
||||
{
|
||||
if (!addr) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = -socketcall.getpeername(context(sockfdo)->handle(), (void *)addr, addrlen);
|
||||
|
||||
addr->sa_family = bsd_family(addr);
|
||||
addr->sa_len = *addrlen;
|
||||
|
||||
return errno > 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
int Plugin::getsockname(Libc::File_descriptor *sockfdo,
|
||||
struct sockaddr *addr,
|
||||
socklen_t *addrlen)
|
||||
{
|
||||
if (!addr) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = -socketcall.getsockname(context(sockfdo)->handle(), (void *)addr, addrlen);
|
||||
|
||||
addr->sa_family = bsd_family(addr);
|
||||
addr->sa_len = *addrlen;
|
||||
|
||||
return errno > 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
int Plugin::getsockopt(Libc::File_descriptor *sockfdo, int level,
|
||||
int optname, void *optval, socklen_t *optlen)
|
||||
{
|
||||
if (level != SOL_SOCKET) {
|
||||
PERR("%s: Unsupported level %d, we only support SOL_SOCKET for now",
|
||||
__func__, level);
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
optname = translate_ops_linux(optname);
|
||||
if (optname < 0) {
|
||||
errno = ENOPROTOOPT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return socketcall.getsockopt(context(sockfdo)->handle(), Lxip::LINUX_SOL_SOCKET,
|
||||
optname, optval, (int *)optlen);
|
||||
}
|
||||
|
||||
|
||||
int Plugin::ioctl(Libc::File_descriptor *sockfdo, int request, char *argp)
|
||||
{
|
||||
switch (request) {
|
||||
|
||||
case FIONBIO:
|
||||
|
||||
context(sockfdo)->non_block(!!*argp);
|
||||
return 0;
|
||||
|
||||
case FIONREAD:
|
||||
|
||||
errno = -socketcall.ioctl(context(sockfdo)->handle(), Lxip::LINUX_FIONREAD,
|
||||
argp);
|
||||
return errno > 0 ? -1 : 0;
|
||||
|
||||
default:
|
||||
|
||||
PERR("unsupported ioctl() request");
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Plugin::listen(Libc::File_descriptor *sockfdo, int backlog)
|
||||
{
|
||||
errno = -socketcall.listen(context(sockfdo)->handle(), backlog);
|
||||
return errno > 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
int Plugin::shutdown(Libc::File_descriptor *sockfdo, int how)
|
||||
{
|
||||
errno = -socketcall.shutdown(context(sockfdo)->handle(), how);
|
||||
return errno > 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: Support timeouts */
|
||||
/* XXX: Check blocking and non-blocking semantics */
|
||||
int Plugin::select(int nfds,
|
||||
fd_set *readfds,
|
||||
fd_set *writefds,
|
||||
fd_set *exceptfds,
|
||||
struct timeval *timeout)
|
||||
{
|
||||
Libc::File_descriptor *sockfdo;
|
||||
struct fd_set fds[3];
|
||||
int bits = 0;
|
||||
|
||||
if (nfds < 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
FD_ZERO(&fds[i]);
|
||||
|
||||
bool block = false;
|
||||
for (int fd = 0; fd <= nfds; fd++) {
|
||||
|
||||
if (fd == nfds && !bits) {
|
||||
fd = -1;
|
||||
block = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
int set = 0;
|
||||
set |= FD_ISSET(fd, readfds);
|
||||
set |= FD_ISSET(fd, writefds);
|
||||
set |= FD_ISSET(fd, exceptfds);
|
||||
|
||||
if (!set)
|
||||
continue;
|
||||
|
||||
sockfdo = Libc::file_descriptor_allocator()->find_by_libc_fd(fd);
|
||||
/* handle only libc_fds that belong to this plugin */
|
||||
if (!sockfdo || (sockfdo->plugin != this))
|
||||
continue;
|
||||
|
||||
/* call IP stack blocking/non-blocking */
|
||||
int mask = socketcall.poll(context(sockfdo)->handle(), block);
|
||||
|
||||
if (mask)
|
||||
block = false;
|
||||
|
||||
if (readfds && (mask & Lxip::POLLIN) && FD_ISSET(fd, readfds) && ++bits)
|
||||
FD_SET(fd, &fds[0]);
|
||||
if (writefds && (mask & Lxip::POLLOUT) && FD_ISSET(fd, writefds) && ++bits)
|
||||
FD_SET(fd, &fds[1]);
|
||||
if (exceptfds && (mask & Lxip::POLLEX) && FD_ISSET(fd, exceptfds) && ++bits)
|
||||
FD_SET(fd, &fds[2]);
|
||||
}
|
||||
|
||||
if (readfds) *readfds = fds[0];
|
||||
if (writefds) *writefds = fds[1];
|
||||
if (exceptfds) *exceptfds = fds[2];
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
|
||||
ssize_t Plugin::read(Libc::File_descriptor *fdo, void *buf, ::size_t count)
|
||||
{
|
||||
return recv(fdo, buf, count, 0);
|
||||
}
|
||||
|
||||
|
||||
ssize_t Plugin::recv(Libc::File_descriptor *sockfdo, void *buf, ::size_t len, int flags)
|
||||
{
|
||||
return recvfrom(sockfdo, buf, len, flags, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
ssize_t Plugin::recvfrom(Libc::File_descriptor *sockfdo, void *buf, ::size_t len, int flags,
|
||||
struct sockaddr *src_addr, socklen_t *addrlen)
|
||||
{
|
||||
int family = 0;
|
||||
|
||||
if (src_addr && addrlen && !(family = linux_family(src_addr, *addrlen))) {
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int recv = socketcall.recv(context(sockfdo)->handle(), buf, len, translate_msg_flags(flags),
|
||||
family, (void *)src_addr, addrlen);
|
||||
|
||||
if (recv < 0) {
|
||||
errno = -recv;
|
||||
return errno == EAGAIN ? 0 : -1;
|
||||
}
|
||||
|
||||
if (src_addr) {
|
||||
src_addr->sa_family = bsd_family(src_addr);
|
||||
src_addr->sa_len = *addrlen;
|
||||
}
|
||||
|
||||
return recv;
|
||||
}
|
||||
|
||||
|
||||
ssize_t Plugin::send(Libc::File_descriptor *sockfdo, const void *buf, ::size_t len, int flags)
|
||||
{
|
||||
return sendto(sockfdo, buf, len, flags, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
ssize_t Plugin::sendto(Libc::File_descriptor *sockfdo, const void *buf,
|
||||
::size_t len, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t addrlen)
|
||||
{
|
||||
int family = 0;
|
||||
|
||||
if (dest_addr && addrlen && !(family = linux_family(dest_addr, addrlen))) {
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int send = socketcall.send(context(sockfdo)->handle(), buf, len, translate_msg_flags(flags),
|
||||
family, (void *)dest_addr);
|
||||
if (send < 0)
|
||||
errno = -send;
|
||||
|
||||
return send < 0 ? -1 : send;
|
||||
}
|
||||
|
||||
|
||||
int Plugin::setsockopt(Libc::File_descriptor *sockfdo, int level,
|
||||
int optname, const void *optval,
|
||||
socklen_t optlen)
|
||||
{
|
||||
if (level != SOL_SOCKET) {
|
||||
PERR("%s: Unsupported level %d, we only support SOL_SOCKET for now",
|
||||
__func__, level);
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
optname = translate_ops_linux(optname);
|
||||
if (optname < 0) {
|
||||
errno = ENOPROTOOPT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return socketcall.setsockopt(context(sockfdo)->handle(), Lxip::LINUX_SOL_SOCKET,
|
||||
optname, optval, optlen);
|
||||
}
|
||||
|
||||
|
||||
Libc::File_descriptor *Plugin::socket(int domain, int type, int protocol)
|
||||
{
|
||||
using namespace Lxip;
|
||||
Handle handle = socketcall.socket(type == SOCK_STREAM ? TYPE_STREAM : TYPE_DGRAM);
|
||||
|
||||
if (!handle.socket) {
|
||||
errno = EBADF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Plugin_context *context = new (Genode::env()->heap()) Plugin_context(handle);
|
||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->alloc(this, context);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
ssize_t Plugin::write(Libc::File_descriptor *fdo, const void *buf, ::size_t count)
|
||||
{
|
||||
return send(fdo, buf, count, 0);
|
||||
}
|
||||
|
||||
|
||||
int Plugin::linux_family(const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
switch (addr->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
|
||||
return LINUX_AF_INET;
|
||||
|
||||
default:
|
||||
|
||||
PERR("Unsupported socket BSD-protocol %u\n", addr->sa_family);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Plugin::bsd_family(struct sockaddr *addr)
|
||||
{
|
||||
/*
|
||||
* Note: Since in Linux 'sa_family' is 16 bit while in BSD it is 8 bit (both
|
||||
* little endian), 'sa_len' will contain the actual family (or lower order
|
||||
* bits) of Linux
|
||||
*/
|
||||
addr->sa_family = addr->sa_len;
|
||||
|
||||
switch (addr->sa_family)
|
||||
{
|
||||
case LINUX_AF_INET: return AF_INET;
|
||||
|
||||
default:
|
||||
|
||||
PERR("Unsupported socket Linux-protocol %u\n", addr->sa_family);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Plugin::translate_msg_flags(int bsd_flags)
|
||||
{
|
||||
using namespace Lxip;
|
||||
int f = 0;
|
||||
|
||||
if (bsd_flags & MSG_OOB) f |= LINUX_MSG_OOB;
|
||||
if (bsd_flags & MSG_PEEK) f |= LINUX_MSG_PEEK;
|
||||
if (bsd_flags & MSG_DONTROUTE) f |= LINUX_MSG_DONTROUTE;
|
||||
if (bsd_flags & MSG_EOR) f |= LINUX_MSG_EOR;
|
||||
if (bsd_flags & MSG_TRUNC) f |= LINUX_MSG_TRUNC;
|
||||
if (bsd_flags & MSG_CTRUNC) f |= LINUX_MSG_CTRUNC;
|
||||
if (bsd_flags & MSG_WAITALL) f |= LINUX_MSG_WAITALL;
|
||||
if (bsd_flags & MSG_NOTIFICATION) PWRN("MSG_NOTIFICATION ignored");
|
||||
if (bsd_flags & MSG_DONTWAIT) f |= LINUX_MSG_DONTWAIT;
|
||||
if (bsd_flags & MSG_EOF) f |= LINUX_MSG_EOF;
|
||||
if (bsd_flags & MSG_NBIO) PWRN("MSG_NBIO ignored");
|
||||
if (bsd_flags & MSG_NOSIGNAL) f |= LINUX_MSG_NOSIGNAL;
|
||||
if (bsd_flags & MSG_COMPAT) f |= LINUX_MSG_COMPAT;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
/* index is Linux, value is BSD */
|
||||
static int sockopts[]
|
||||
{
|
||||
0, /* 0 */
|
||||
SO_DEBUG,
|
||||
SO_REUSEADDR,
|
||||
SO_TYPE,
|
||||
SO_ERROR,
|
||||
SO_DONTROUTE, /* 5 */
|
||||
SO_BROADCAST,
|
||||
SO_SNDBUF,
|
||||
SO_RCVBUF,
|
||||
SO_KEEPALIVE,
|
||||
SO_OOBINLINE, /* 10 */
|
||||
/* SO_NOCHECK */ 0,
|
||||
/* SO_PRIORITY */ 0,
|
||||
SO_LINGER,
|
||||
/* SO_BSDCOMPAT */ 0,
|
||||
SO_REUSEPORT, /* 15 */
|
||||
/* SO_PASSCRED */ 0,
|
||||
/* SO_PEERCRED */ 0,
|
||||
SO_RCVLOWAT,
|
||||
SO_SNDLOWAT,
|
||||
SO_RCVTIMEO, /* 20 */
|
||||
SO_SNDTIMEO,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0, /* 25 */
|
||||
0,
|
||||
0,
|
||||
SO_PEERLABEL,
|
||||
SO_TIMESTAMP,
|
||||
SO_ACCEPTCONN, /* 30 */
|
||||
-1
|
||||
};
|
||||
|
||||
|
||||
int Plugin::translate_ops_linux(int optname)
|
||||
{
|
||||
for (int i = 0; sockopts[i] > -1; i++)
|
||||
if (sockopts[i] == optname)
|
||||
return i;
|
||||
|
||||
PERR("Unsupported sockopt %d\n", optname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
} /* unnamed namespace */
|
||||
|
||||
|
||||
void create_lxip_plugin()
|
||||
{
|
||||
static Plugin lxip_plugin;
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/**
|
||||
* \brief Back-end driver for IP stack
|
||||
* \author Sebastian Sumpf
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2013-09-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
#include <lx_emul.h>
|
||||
#include <nic.h>
|
||||
|
||||
static struct net_device *_dev;
|
||||
|
||||
static int driver_net_open(struct net_device *dev)
|
||||
{
|
||||
printk("%s called\n",__func__);
|
||||
_dev = dev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int driver_net_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct net_device_stats *stats = (struct net_device_stats*) netdev_priv(dev);
|
||||
int len = skb->len;
|
||||
void* addr = skb->data;
|
||||
|
||||
/* transmit to nic-session */
|
||||
while (net_tx(addr, len)) {
|
||||
/* tx queue is full, could not enqueue packet */
|
||||
printk("TX full\n");
|
||||
}
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
/* save timestamp */
|
||||
dev->trans_start = jiffies;
|
||||
|
||||
stats->tx_packets++;
|
||||
stats->tx_bytes += len;
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
||||
void net_driver_rx(void *addr, unsigned long size)
|
||||
{
|
||||
struct net_device_stats *stats;
|
||||
|
||||
if (!_dev)
|
||||
return;
|
||||
|
||||
stats = (struct net_device_stats*) netdev_priv(_dev);
|
||||
|
||||
/* allocate skb */
|
||||
struct sk_buff *skb = dev_alloc_skb(size + 4);
|
||||
if (!skb) {
|
||||
printk(KERN_NOTICE "genode_net_rx: low on mem - packet dropped!\n");
|
||||
stats->rx_dropped++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* copy packet */
|
||||
memcpy(skb_put(skb, size), addr, size);
|
||||
|
||||
skb->dev = _dev;
|
||||
skb->protocol = eth_type_trans(skb, _dev);
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
|
||||
netif_receive_skb(skb);
|
||||
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += size;
|
||||
}
|
||||
|
||||
|
||||
static const struct net_device_ops driver_net_ops =
|
||||
{
|
||||
.ndo_open = driver_net_open,
|
||||
.ndo_start_xmit = driver_net_xmit,
|
||||
};
|
||||
|
||||
|
||||
static int driver_init(void)
|
||||
{
|
||||
struct net_device *dev;
|
||||
int err = -ENODEV;
|
||||
|
||||
dev = alloc_etherdev(0);
|
||||
|
||||
if (!(dev = alloc_etherdev(0)))
|
||||
goto out;
|
||||
|
||||
dev->netdev_ops = &driver_net_ops;
|
||||
|
||||
/* set MAC */
|
||||
net_mac(dev->dev_addr, ETH_ALEN);
|
||||
|
||||
if ((err = register_netdev(dev))) {
|
||||
panic("driver: Could not register back-end %d\n", err);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
free_netdev(dev);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
module_init(driver_init);
|
||||
|
||||
|