From 5e17fef89809b0df17a814af064cdeb138211188 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Mon, 26 Aug 2013 13:58:58 +0200 Subject: [PATCH] lxip: Port of the Linux TCP/IP stack --- dde_linux/Makefile | 91 +- dde_linux/README | 8 + dde_linux/files.list | 228 ++ dde_linux/include/lxip/lxip.h | 97 + dde_linux/lib/mk/libc_lxip.mk | 5 + dde_linux/lib/mk/lxip.mk | 94 + dde_linux/lib/mk/usb.inc | 9 +- dde_linux/lxip_header.list | 85 + dde_linux/patches/icmp.patch | 12 + dde_linux/patches/ip_config.patch | 36 + dde_linux/patches/skbuff.patch | 30 + dde_linux/patches/tcp.patch | 32 + dde_linux/src/lib/libc_lxip/init.cc | 24 + dde_linux/src/lib/libc_lxip/plugin.cc | 657 +++++ dde_linux/src/lib/lxip/driver.c | 122 + dde_linux/src/lib/lxip/dummies.cc | 521 ++++ dde_linux/src/lib/lxip/env.cc | 20 + dde_linux/src/lib/lxip/include/env.h | 30 + dde_linux/src/lib/lxip/include/init.h | 21 + dde_linux/src/lib/lxip/include/linux/ip.h | 2 + dde_linux/src/lib/lxip/include/linux/ipv6.h | 2 + dde_linux/src/lib/lxip/include/linux/module.h | 3 + .../lib/lxip/include/linux/netfilter_arp.h | 1 + .../lib/lxip/include/linux/netfilter_ipv4.h | 1 + .../src/lib/lxip/include/linux/sockios.h | 2 + dde_linux/src/lib/lxip/include/lx_emul.h | 2618 +++++++++++++++++ .../src/lib/lxip/include/net/fib_rules.h | 1 + .../src/lib/lxip/include/net/gen_stats.h | 1 + dde_linux/src/lib/lxip/include/net/inet_ecn.h | 1 + dde_linux/src/lib/lxip/include/net/xfrm.h | 6 + dde_linux/src/lib/lxip/include/nic.h | 27 + .../src/lib/lxip/include/packet_handler.h | 73 + dde_linux/src/lib/lxip/init.c | 78 + dde_linux/src/lib/lxip/lxc_emul.c | 393 +++ dde_linux/src/lib/lxip/lxcc_emul.cc | 635 ++++ dde_linux/src/lib/lxip/nic_handler.cc | 148 + dde_linux/src/lib/lxip/socket.c | 115 + dde_linux/src/lib/lxip/socket_handler.cc | 630 ++++ dde_linux/src/lib/lxip/timer_handler.cc | 145 + ports/run/netperf.inc | 9 + 40 files changed, 6924 insertions(+), 89 deletions(-) create mode 100644 dde_linux/files.list create mode 100644 dde_linux/include/lxip/lxip.h create mode 100644 dde_linux/lib/mk/libc_lxip.mk create mode 100644 dde_linux/lib/mk/lxip.mk create mode 100644 dde_linux/lxip_header.list create mode 100644 dde_linux/patches/icmp.patch create mode 100644 dde_linux/patches/ip_config.patch create mode 100644 dde_linux/patches/skbuff.patch create mode 100644 dde_linux/patches/tcp.patch create mode 100644 dde_linux/src/lib/libc_lxip/init.cc create mode 100644 dde_linux/src/lib/libc_lxip/plugin.cc create mode 100644 dde_linux/src/lib/lxip/driver.c create mode 100644 dde_linux/src/lib/lxip/dummies.cc create mode 100644 dde_linux/src/lib/lxip/env.cc create mode 100644 dde_linux/src/lib/lxip/include/env.h create mode 100644 dde_linux/src/lib/lxip/include/init.h create mode 100644 dde_linux/src/lib/lxip/include/linux/ip.h create mode 100644 dde_linux/src/lib/lxip/include/linux/ipv6.h create mode 100644 dde_linux/src/lib/lxip/include/linux/module.h create mode 100644 dde_linux/src/lib/lxip/include/linux/netfilter_arp.h create mode 100644 dde_linux/src/lib/lxip/include/linux/netfilter_ipv4.h create mode 100644 dde_linux/src/lib/lxip/include/linux/sockios.h create mode 100644 dde_linux/src/lib/lxip/include/lx_emul.h create mode 100644 dde_linux/src/lib/lxip/include/net/fib_rules.h create mode 100644 dde_linux/src/lib/lxip/include/net/gen_stats.h create mode 100644 dde_linux/src/lib/lxip/include/net/inet_ecn.h create mode 100644 dde_linux/src/lib/lxip/include/net/xfrm.h create mode 100644 dde_linux/src/lib/lxip/include/nic.h create mode 100644 dde_linux/src/lib/lxip/include/packet_handler.h create mode 100644 dde_linux/src/lib/lxip/init.c create mode 100644 dde_linux/src/lib/lxip/lxc_emul.c create mode 100644 dde_linux/src/lib/lxip/lxcc_emul.cc create mode 100644 dde_linux/src/lib/lxip/nic_handler.cc create mode 100644 dde_linux/src/lib/lxip/socket.c create mode 100644 dde_linux/src/lib/lxip/socket_handler.cc create mode 100644 dde_linux/src/lib/lxip/timer_handler.cc diff --git a/dde_linux/Makefile b/dde_linux/Makefile index 955d4054b..6e4f6a964 100644 --- a/dde_linux/Makefile +++ b/dde_linux/Makefile @@ -10,87 +10,8 @@ ECHO = @echo PATCHES := $(shell find patches -name \*.patch) LINUX = linux-3.9 -LINUX_TBZ2 = $(LINUX).tar.bz2 -LINUX_URL = http://www.kernel.org/pub/linux/kernel/v3.x/$(LINUX_TBZ2) - -# Linux utilities -CONTENT += include/linux/list.h -CONTENT += $(addprefix include/linux/,pci_ids.h usb.h hid.h hiddev.h input.h mod_devicetable.h) -CONTENT += include/linux/byteorder/generic.h -CONTENT += include/linux/swab.h - -CONTENT += $(addprefix include/asm-generic/bitops/,__ffs.h non-atomic.h) - -CONTENT_UAPI = byteorder/little_endian.h hid.h input.h pci_regs.h usb/ch11.h \ - usb/ch9.h -CONTENT_USB = ch9.h phy.h -CONTENT += $(addprefix include/uapi/linux/,$(CONTENT_UAPI)) -CONTENT += $(addprefix include/linux/usb/,$(CONTENT_USB)) -CONTENT += include/uapi/asm-generic/ioctl.h - -# USB core -CONTENT_CORE = buffer.c config.c devices.c driver.c endpoint.c file.c generic.c \ - hcd.c hcd-pci.c hub.h hub.c message.c notify.c quirks.c port.c \ - urb.c usb.c usb.h -CONTENT += $(addprefix drivers/usb/core/,$(CONTENT_CORE)) -CONTENT += drivers/usb/usb-common.c -CONTENT_INCLUDE_USB := ehci_def.h hcd.h input.h otg.h quirks.h storage.h -CONTENT += $(addprefix include/linux/usb/,$(CONTENT_INCLUDE_USB)) - -# needed by usb/core/devio.c -CONTENT += include/asm-generic/ioctl.h - -# USB host-controller driver -CONTENT_USB_HOST := ehci.h ehci-hcd.c ehci-hub.c ehci-dbg.c ehci-mem.c \ - ehci-omap.c ehci-q.c ehci-pci.c ehci-s5p.c ehci-sched.c \ - ehci-sysfs.c ehci-timer.c -CONTENT_USB_HOST += ohci.h ohci-hcd.c ohci-hub.c ohci-dbg.c ohci-mem.c \ - ohci-q.c ohci-pci.c -CONTENT_USB_HOST += uhci-hcd.h uhci-hcd.c uhci-debug.c uhci-q.c uhci-hub.c \ - uhci-pci.c -CONTENT_USB_HOST += xhci-dbg.c xhci-ext-caps.h xhci-hub.c xhci-mem.c \ - xhci-plat.c xhci-ring.c xhci.h xhci.c -CONTENT_USB_HOST += pci-quirks.h pci-quirks.c -CONTENT += $(addprefix drivers/usb/host/,$(CONTENT_USB_HOST)) - -# USB storage driver -CONTENT += drivers/usb/storage/ -CONTENT += include/linux/usb_usual.h - -# SCSI support for storage -CONTENT += $(addprefix drivers/scsi/,scsi.h scsi.c constants.c scsi_priv.h scsi_logging.h) -CONTENT += $(addprefix include/scsi/,scsi.h scsi_host.h) - -# USB hid driver -CONTENT += drivers/hid/hid-input.c drivers/hid/hid-generic.c drivers/hid/hid-core.c drivers/hid/hid-ids.h -CONTENT += drivers/hid/hid-cherry.c drivers/hid/usbhid - -# needed by USB hid -CONTENT_INPUT := input.c evdev.c input-compat.h -CONTENT += $(addprefix drivers/input/,$(CONTENT_INPUT)) -CONTENT += include/linux/input/mt.h - -# usb network driver -CONTENT_NET = usbnet.c -# Panda board -CONTENT_NET += smsc95xx.c smsc95xx.h -# Arndale board -CONTENT_NET += asix_devices.c asix_common.c ax88172a.c ax88179_178a.c asix.h - -CONTENT += $(addprefix drivers/net/usb/,$(CONTENT_NET)) -CONTENT += include/linux/usb/usbnet.h include/linux/netdev_features.h - -# DWC3 controller -CONTENT_DWC3 = core.c core.h dwc3-exynos.c host.c io.h -CONTENT += $(addprefix drivers/usb/dwc3/,$(CONTENT_DWC3)) -CONTENT += include/linux/platform_data/dwc3-exynos.h - -# OMAP -CONTENT += include/linux/platform_data/usb-omap.h - -# Arndale -CONTENT += arch/arm/plat-samsung/include/plat/usb-phy.h -CONTENT += include/linux/platform_data/usb-ehci-s5p.h +LINUX_TGZ = $(LINUX).tar.gz +LINUX_URL = http://www.kernel.org/pub/linux/kernel/v3.x/$(LINUX_TGZ) # Raspberry Pi DWC_OTG_GIT_URL := https://github.com/nfeske/dwc_otg.git @@ -127,13 +48,13 @@ prepare_rpi: prepare git reset --hard HEAD && git checkout $(DWC_OTG_GIT_BRANCH) $(CONTRIB_DIR)/.prepared: Makefile -$(CONTRIB_DIR)/.prepared: $(DOWNLOAD_DIR)/$(LINUX_TBZ2) +$(CONTRIB_DIR)/.prepared: $(DOWNLOAD_DIR)/$(LINUX_TGZ) $(ECHO) "extracting source code to '$(CONTRIB_DIR)'" - $(VERBOSE)tar xfj $< --transform "s/$(LINUX)/$(CONTRIB_DIR)/" $(addprefix $(LINUX)/,$(CONTENT)) + $(VERBOSE)tar xfz $< --transform "s{$(LINUX){$(CONTRIB_DIR){" --files-from files.list + $(VERBOSE)tar xfz $< --transform "s{$(LINUX){$(CONTRIB_DIR)/lxip{" --files-from lxip_header.list $(VERBOSE)touch $@ $(ECHO) "applying patches to '$(CONTRIB_DIR)/'" $(VERBOSE)for i in $(PATCHES); do patch -d $(CONTRIB_DIR) -p1 < $$i; done - $(VERBOSE)ln -sf ../../uapi/linux/usb/ch11.h $(CONTRIB_DIR)/include/linux/usb/ch11.h $(VERBOSE)touch $(CONTRIB_DIR)/drivers/usb/dwc3/gadget.h $(VERBOSE)touch $(CONTRIB_DIR)/drivers/usb/dwc3/debug.h @@ -141,7 +62,7 @@ $(CONTRIB_DIR)/.prepared: $(DOWNLOAD_DIR)/$(LINUX_TBZ2) $(DOWNLOAD_DIR): $(VERBOSE)mkdir -p $@ -$(DOWNLOAD_DIR)/$(LINUX_TBZ2): $(DOWNLOAD_DIR) +$(DOWNLOAD_DIR)/$(LINUX_TGZ): $(DOWNLOAD_DIR) $(ECHO) "downloading source code to '$@'" $(VERBOSE)cd $(DOWNLOAD_DIR); wget -c $(LINUX_URL) $(VERBOSE)touch $@ diff --git a/dde_linux/README b/dde_linux/README index b81708316..52c44fa9a 100644 --- a/dde_linux/README +++ b/dde_linux/README @@ -74,3 +74,11 @@ cannot be accessed via the host controller making it impossible to retrieve the devices hardware address. If this is the case and no 'mac' attribute is given a fallback address will be assigned to the network device. Note that the fallback address will always be the same. + +LXIP +#### + +LXIP is a port of the Linux TCP/IP stack to Genode. It is build as a shared +library named 'lxip.lib.so'. The IP stack can be interfaced using Genode's +version of 'libc' by linking your application to 'lxip_libc' plugin in your +'target.mk' file. diff --git a/dde_linux/files.list b/dde_linux/files.list new file mode 100644 index 000000000..a600543a6 --- /dev/null +++ b/dde_linux/files.list @@ -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 + diff --git a/dde_linux/include/lxip/lxip.h b/dde_linux/include/lxip/lxip.h new file mode 100644 index 000000000..3c5ae1f58 --- /dev/null +++ b/dde_linux/include/lxip/lxip.h @@ -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 + +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_ */ diff --git a/dde_linux/lib/mk/libc_lxip.mk b/dde_linux/lib/mk/libc_lxip.mk new file mode 100644 index 000000000..635c43dbc --- /dev/null +++ b/dde_linux/lib/mk/libc_lxip.mk @@ -0,0 +1,5 @@ +SRC_CC = init.cc plugin.cc + +vpath %.cc $(REP_DIR)/src/lib/libc_lxip + +LIBS += lxip libc libc_resolv diff --git a/dde_linux/lib/mk/lxip.mk b/dde_linux/lib/mk/lxip.mk new file mode 100644 index 000000000..1a34c7373 --- /dev/null +++ b/dde_linux/lib/mk/lxip.mk @@ -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) diff --git a/dde_linux/lib/mk/usb.inc b/dde_linux/lib/mk/usb.inc index 36fdbaceb..f5b700328 100644 --- a/dde_linux/lib/mk/usb.inc +++ b/dde_linux/lib/mk/usb.inc @@ -17,7 +17,7 @@ CC_OLEVEL = -O2 # 'contrib' before falling back to our custom 'lx_emul.h' header. # INC_DIR += $(LIB_INC_DIR) -INC_DIR += $(CONTRIB_DIR)/include $(CONTRIB_DIR) +INC_DIR += $(CONTRIB_DIR)/include $(CONTRIB_DIR)/include/uapi $(CONTRIB_DIR) CC_OPT += -U__linux__ -D__KERNEL__ CC_OPT += -DCONFIG_USB_DEVICEFS -DCONFIG_HOTPLUG -DDEBUG @@ -28,6 +28,7 @@ CC_WARN = -Wall -Wno-unused-variable -Wno-uninitialized \ CC_C_OPT += -Wno-implicit-function-declaration -Wno-unused-but-set-variable \ -Wno-pointer-sign +CXX_OPT = -fpermissive # # Suffix of global 'module_init' function # @@ -57,13 +58,13 @@ SRC_C += $(addprefix scsi/,scsi.c constants.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) +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\///") +NO_GEN_INCLUDES := $(shell cd $(CONTRIB_DIR)/include; find -name "*.h" | sed "s/.\///" | sed "s/.*include\///") GEN_INCLUDES := $(filter-out $(NO_GEN_INCLUDES),$(GEN_INCLUDES)) # diff --git a/dde_linux/lxip_header.list b/dde_linux/lxip_header.list new file mode 100644 index 000000000..2d0386ca1 --- /dev/null +++ b/dde_linux/lxip_header.list @@ -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 diff --git a/dde_linux/patches/icmp.patch b/dde_linux/patches/icmp.patch new file mode 100644 index 000000000..5513b1fc2 --- /dev/null +++ b/dde_linux/patches/icmp.patch @@ -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; diff --git a/dde_linux/patches/ip_config.patch b/dde_linux/patches/ip_config.patch new file mode 100644 index 000000000..c95817dbe --- /dev/null +++ b/dde_linux/patches/ip_config.patch @@ -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 */ + diff --git a/dde_linux/patches/skbuff.patch b/dde_linux/patches/skbuff.patch new file mode 100644 index 000000000..3360a6ec4 --- /dev/null +++ b/dde_linux/patches/skbuff.patch @@ -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; diff --git a/dde_linux/patches/tcp.patch b/dde_linux/patches/tcp.patch new file mode 100644 index 000000000..4b9b04f94 --- /dev/null +++ b/dde_linux/patches/tcp.patch @@ -0,0 +1,32 @@ +From 8b2f74f2258b62ca0e62656cdccbc9159aeab893 Mon Sep 17 00:00:00 2001 +From: Sebastian Sumpf +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 + diff --git a/dde_linux/src/lib/libc_lxip/init.cc b/dde_linux/src/lib/libc_lxip/init.cc new file mode 100644 index 000000000..9cd46c43f --- /dev/null +++ b/dde_linux/src/lib/libc_lxip/init.cc @@ -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 + +extern void create_lxip_plugin(); + +void __attribute__((constructor)) init_libc_lxip(void) +{ + PDBG("init_libc_lxip()\n"); + create_lxip_plugin(); +} diff --git a/dde_linux/src/lib/libc_lxip/plugin.cc b/dde_linux/src/lib/libc_lxip/plugin.cc new file mode 100644 index 000000000..842fb43d5 --- /dev/null +++ b/dde_linux/src/lib/libc_lxip/plugin.cc @@ -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 +#include +#include +#include + +/* Genode includes */ +#include +#include + +/* Libc plugin includes */ +#include +#include + +/* Lxip includes */ +#include + + +/************************** + ** 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(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; +} diff --git a/dde_linux/src/lib/lxip/driver.c b/dde_linux/src/lib/lxip/driver.c new file mode 100644 index 000000000..877aae34f --- /dev/null +++ b/dde_linux/src/lib/lxip/driver.c @@ -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 +#include + +#include +#include + +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); + + diff --git a/dde_linux/src/lib/lxip/dummies.cc b/dde_linux/src/lib/lxip/dummies.cc new file mode 100644 index 000000000..ea9789345 --- /dev/null +++ b/dde_linux/src/lib/lxip/dummies.cc @@ -0,0 +1,521 @@ +/** + * \brief Dummy functions + * \author Sebastian Sumpf + * \date 2013-08-26 + */ + +/* + * 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 + +extern "C" { + typedef long DUMMY; + +enum { + SHOW_DUMMY = 0, + SHOW_SKIP = 0, + SHOW_RET = 0, +}; + +#define DUMMY(retval, name) \ + DUMMY name(void) { \ + if (SHOW_DUMMY) \ + PDBG( #name " called (from %p) not implemented", __builtin_return_address(0)); \ + return retval; \ +} + +#define DUMMY_SKIP(retval, name) \ + DUMMY name(void) { \ + if (SHOW_SKIP) \ + PLOG( #name " called (from %p) skipped", __builtin_return_address(0)); \ + return retval; \ +} + +#define DUMMY_RET(retval, name) \ + DUMMY name(void) { \ + if (SHOW_RET) \ + PWRN( #name " called (from %p) return %d", __builtin_return_address(0), retval); \ + return retval; \ +} + + +/* + * Changed return values + */ +DUMMY_RET(0, in_irq) +DUMMY_RET(0, inet_twsk_alloc) +DUMMY_RET(0, ipv6_only_sock) +DUMMY_RET(0, netpoll_receive_skb) +DUMMY_RET(0, netpoll_rx_disable) +DUMMY_RET(1, nf_hook) +DUMMY_RET(0, notifier_to_errno) +DUMMY_RET(0, net_hash_mix) +DUMMY_RET(0, netdev_kobject_init) +DUMMY_RET(0, netdev_register_kobject) +DUMMY_RET(0, netpoll_rx) +DUMMY_RET(0, nla_put) +DUMMY_RET(1, num_possible_cpus) +DUMMY_RET(0, read_seqretry) +DUMMY_RET(0, poll_does_not_wait) +DUMMY_RET(0, secpath_exists) +DUMMY_RET(0, security_inet_conn_request) +DUMMY_RET(0, security_sk_alloc) +DUMMY_RET(0, signal_pending) +DUMMY_RET(0, sk_filter) +DUMMY_RET(0, sock_tx_timestamp) +DUMMY_RET(0, sscanf) +DUMMY_RET(0, static_key_false) +DUMMY_RET(0, vlan_tx_nonzero_tag_present) +DUMMY_RET(0, vlan_tx_tag_present) +DUMMY_RET(1, xfrm4_policy_check) +DUMMY_RET(0, xfrm_sk_clone_policy) +DUMMY_RET(0, xfrm_decode_session_reverse) + + +/* + * Unnecessary to trace + */ +DUMMY_SKIP( 0, ASSERT_RTNL) +DUMMY_SKIP(-1, debug_check_no_locks_freed) +DUMMY_SKIP(-1, local_bh_disable) +DUMMY_SKIP(-1, local_bh_enable) +DUMMY_SKIP(-1, local_irq_disable) +DUMMY_SKIP(-1, local_irq_enable) +DUMMY_SKIP(-1, local_irq_restore) +DUMMY_SKIP(-1, local_irq_save) +DUMMY_SKIP(-1, lockdep_init_map) +DUMMY_SKIP(-1, lockdep_set_class_and_name) +DUMMY_SKIP(-1, kmemcheck_annotate_variable) +DUMMY_SKIP(-1, might_sleep) +DUMMY_SKIP(-1, mutex_acquire) +DUMMY_SKIP(-1, mutex_init) +DUMMY_SKIP(-1, mutex_release) +DUMMY_SKIP(-1, mutex_unlock) +DUMMY_SKIP(-1, prefetchw) +DUMMY_SKIP(-1, mutex_lock) +DUMMY_SKIP(-1, rcu_read_lock) +DUMMY_SKIP(-1, rcu_read_unlock) +DUMMY_SKIP(-1, rcu_read_lock_bh) +DUMMY_SKIP(-1, rcu_read_unlock_bh) +DUMMY_SKIP(-1, read_lock) +DUMMY_SKIP(-1, read_seqbegin) +DUMMY_SKIP(-1, read_unlock) +DUMMY_SKIP(-1, read_lock_bh) +DUMMY_SKIP(-1, read_unlock_bh) +DUMMY_SKIP(-1, rwlock_init) +DUMMY_SKIP(-1, seqlock_init) +DUMMY_SKIP(-1, smp_mb) +DUMMY_SKIP(-1, smp_rmb) +DUMMY_SKIP(-1, smp_wmb) +DUMMY_SKIP(-1, spin_lock_irqsave) +DUMMY_SKIP( 1, spin_trylock) +DUMMY_SKIP(-1, spin_unlock_irqrestore) +DUMMY_SKIP(-1, synchronize_rcu) +DUMMY_SKIP(-1, trace_kfree_skb) +DUMMY_SKIP(-1, trace_consume_skb) +DUMMY_SKIP(-1, trace_net_dev_xmit) +DUMMY_SKIP(-1, trace_netif_receive_skb) +DUMMY_SKIP(-1, write_lock) +DUMMY_SKIP(-1, write_lock_bh) +DUMMY_SKIP(-1, write_lock_irq) +DUMMY_SKIP(-1, write_seqlock) +DUMMY_SKIP(-1, write_seqlock_bh) +DUMMY_SKIP(-1, write_sequnlock) +DUMMY_SKIP(-1, write_sequnlock_bh) +DUMMY_SKIP(-1, write_unlock) +DUMMY_SKIP(-1, write_unlock_bh) +DUMMY_SKIP(-1, write_unlock_irq) + +/* requires CONFIG_MEMCG_KMEM */ +DUMMY_SKIP(-1, sock_release_memcg) + +DUMMY_SKIP(-1, waitqueue_active) +DUMMY_SKIP(-1, wake_up) + +/* + * Test + */ +DUMMY_SKIP(-1, rtmsg_ifinfo) +DUMMY_RET(0, rtnl_is_locked) +DUMMY_SKIP(-1, rtnl_lock) +DUMMY(-1, rtnl_notify) +DUMMY(-1, rtnl_set_sk_err) +DUMMY_SKIP(-1, rtnl_unlock) +DUMMY_RET(0, rtnetlink_put_metrics) +DUMMY(-1, rtnl_af_register) +DUMMY(-1, rtnl_put_cacheinfo) +DUMMY_SKIP(-1, rtnl_register) +DUMMY(-1, rtnl_unicast) + + + +/* + * Dummies + */ +DUMMY(-1, access_ok) +DUMMY(-1, add_device_randomness) +DUMMY(-1, addrconf_finite_timeout) +DUMMY(-1, addrconf_timeout_fixup) +DUMMY(-1, add_wait_queue) +DUMMY(-1, add_wait_queue_exclusive) +DUMMY(-1, atomic_notifier_call_chain) +DUMMY(-1, atomic_notifier_chain_register) +DUMMY(-1, atomic_notifier_chain_unregister) +DUMMY(-1, audit_enabled) +DUMMY(-1, audit_get_loginuid) +DUMMY(-1, audit_get_sessionid) +DUMMY(-1, audit_log) +DUMMY(-1, autoremove_wake_function) +DUMMY(-1, blocking_notifier_chain_unregister) +DUMMY(-1, call_netevent_notifiers) +DUMMY(-1, cancel_delayed_work) +DUMMY(-1, cancel_delayed_work_sync) +DUMMY(-1, capable) +DUMMY(-1, cipso_v4_validate) +DUMMY(-1, __clear_bit) +DUMMY(-1, clamp) +DUMMY(-1, clear_bit) +DUMMY(-1, cond_resched) +DUMMY(-1, cond_resched_softirq) +DUMMY(-1, __copy_from_user_nocache) +DUMMY(-1, csum_block_sub) +DUMMY(-1, csum_replace2) +DUMMY(-1, csum_sub) +DUMMY(-1, csum_unfold) +DUMMY(-1, current) +DUMMY(-1, current_egid) +DUMMY(-1, current_text_addr) +DUMMY(-1, current_uid_gid) +DUMMY(-1, del_timer_sync) +DUMMY(-1, dev_driver_string) +DUMMY(-1, device_rename) +DUMMY(-1, dev_ioctl) +DUMMY(-1, dev_is_pci) +DUMMY(-1, dev_load) +DUMMY(-1, dev_name) +DUMMY(-1, dev_num_vf) +DUMMY(-1, dev_printk_emit) +DUMMY(-1, div64_u64) +DUMMY(-1, div_u64) +DUMMY(-1, do_softirq) +DUMMY(-1, dump_stack) +DUMMY(-1, ether_addr_equal_64bits) +DUMMY(-1, exit_fn) +DUMMY(-1, file_inode) +DUMMY(-1, finish_wait) +DUMMY(-1, __fls) +DUMMY(-1, fls64) +DUMMY(-1, free_pages) +DUMMY(-1, from_kgid) +DUMMY(-1, from_kgid_munged) +DUMMY(-1, from_kuid) +DUMMY(-1, from_kuid_munged) +DUMMY(-1, generic_pipe_buf_confirm) +DUMMY(-1, generic_pipe_buf_map) +DUMMY(-1, generic_pipe_buf_unmap) +DUMMY(-1, gen_kill_estimator) +DUMMY(-1, get_current_groups) +DUMMY(-1, get_ds) +DUMMY(-1, __get_free_pages) +DUMMY(-1, get_fs) +DUMMY(-1, get_net_ns_by_fd) +DUMMY(-1, get_net_ns_by_pid) +DUMMY(-1, getnstimeofday) +DUMMY(-1, get_nulls_value) +DUMMY(-1, get_options) +DUMMY(-1, get_page) +DUMMY(-1, get_random_bytes) +DUMMY(-1, gfp_pfmemalloc_allowed) +DUMMY(-1, gid_lte) +DUMMY(-1, hash32_ptr) +DUMMY(-1, hex_to_bin) +DUMMY(-1, hlist_add_after_rcu) +DUMMY(-1, hlist_add_before_rcu) +DUMMY(-1, hlist_nulls_del) +DUMMY(-1, hlist_nulls_empty) +DUMMY(-1, hotcpu_notifier) +DUMMY(-1, hweight32) +DUMMY(-1, hweight64) +DUMMY(-1, inet_ctl_sock_destroy) +DUMMY(-1, inet_diag_dump_icsk) +DUMMY(-1, inet_diag_dump_one_icsk) +DUMMY(-1, inet_diag_register) +DUMMY(-1, inet_diag_unregister) +DUMMY(-1, INET_ECN_dontxmit) +DUMMY(-1, INET_ECN_is_not_ect) +DUMMY(-1, INET_ECN_xmit) +DUMMY(-1, inet_twdr_hangman) +DUMMY(-1, inet_twdr_twcal_tick) +DUMMY(-1, inet_twdr_twkill_work) +DUMMY(-1, inet_twsk_bind_unhash) +DUMMY(-1, inet_twsk_deschedule) +DUMMY(-1, __inet_twsk_hashdance) +DUMMY(-1, inet_twsk_purge) +DUMMY(-1, inet_twsk_put) +DUMMY(-1, inet_twsk_schedule) +DUMMY(-1, inet_twsk_unhash) +DUMMY(-1, inet_v6_ipv6only) +DUMMY(-1, INIT_DEFERRABLE_WORK) +DUMMY(-1, INIT_HLIST_NULLS_HEAD) +DUMMY(-1, init_user_ns) +DUMMY(-1, init_waitqueue_head) +DUMMY(-1, INIT_WORK) +DUMMY(-1, in_softirq) +DUMMY(-1, ip4_datagram_connect) +DUMMY(-1, ip4_datagram_release_cb) +DUMMY(-1, ip_check_mc_rcu) +DUMMY(-1, ip_mc_destroy_dev) +DUMMY(-1, ip_mc_down) +DUMMY(-1, ip_mc_drop_socket) +DUMMY(-1, ip_mc_gsfget) +DUMMY(-1, ip_mc_init_dev) +DUMMY(-1, ip_mc_join_group) +DUMMY(-1, ip_mc_leave_group) +DUMMY(-1, ip_mc_msfget) +DUMMY(-1, ip_mc_msfilter) +DUMMY(-1, ip_mc_remap) +DUMMY(-1, ip_mc_sf_allow) +DUMMY(-1, ip_mc_source) +DUMMY(-1, ip_mc_unmap) +DUMMY(-1, ip_mc_up) +DUMMY(-1, ip_mroute_getsockopt) +DUMMY(-1, ip_mroute_opt) +DUMMY(-1, ip_mroute_setsockopt) +DUMMY(-1, ipv4_is_lbcast) +DUMMY(-1, ipv4_is_local_multicast) +DUMMY(-1, ipv4_is_zeronet) +DUMMY(-1, irqs_disabled) +DUMMY(-1, is_a_nulls) +DUMMY(-1, is_multicast_ether_addr) +DUMMY(-1, is_valid_ether_addr) +DUMMY(-1, is_vlan_dev) +DUMMY(-1, jiffies_delta_to_clock_t) +DUMMY(-1, jiffies_to_clock_t) +DUMMY(-1, jiffies_to_msecs) +DUMMY(-1, jiffies_to_usecs) +DUMMY(-1, kernel_sendmsg) +DUMMY(-1, kmem_cache_destroy) +DUMMY(-1, kobject_put) +DUMMY(-1, kobject_uevent) +DUMMY(-1, krealloc) +DUMMY(-1, kref_init) +DUMMY(-1, kref_put) +DUMMY(-1, kstrdup) +DUMMY(-1, kstrtoul) +DUMMY(-1, ktime_equal) +DUMMY(-1, ktime_to_timespec) +DUMMY(-1, ktime_to_timeval) +DUMMY(-1, ktime_us_delta) +DUMMY(-1, kunmap) +DUMMY(-1, kunmap_atomic) +DUMMY(-1, linkwatch_fire_event) +DUMMY(-1, linkwatch_forget_dev) +DUMMY(-1, linkwatch_init_dev) +DUMMY(-1, linkwatch_run_queue) +DUMMY(-1, list_del_rcu) +DUMMY(-1, list_replace_rcu) +DUMMY(-1, local_softirq_pending) +DUMMY(-1, lockdep_rtnl_is_held) +DUMMY(-1, min) +DUMMY(-1, mod_delayed_work) +DUMMY(-1, module_put) +DUMMY(-1, move_addr_to_kernel) +DUMMY(-1, mq_qdisc_ops) +DUMMY(-1, msecs_to_jiffies) +DUMMY(-1, msleep) +DUMMY(-1, mutex_is_locked) +DUMMY(-1, need_resched) +DUMMY(-1, netdev_queue_update_kobjects) +DUMMY(-1, netdev_unregister_kobject) +DUMMY(-1, net_dmaengine_get) +DUMMY(-1, net_dmaengine_put) +DUMMY(-1, net_eq) +DUMMY(-1, net_namespace_list) +DUMMY(-1, netpoll_poll_lock) +DUMMY(-1, netpoll_poll_unlock) +DUMMY(-1, netpoll_rx_enable) +DUMMY(-1, netpoll_rx_on) +DUMMY(-1, next_pseudo_random32) +DUMMY(-1, nf_bridge_pad) +DUMMY(-1, nf_ct_attach) +DUMMY(-1, nla_find) +DUMMY(-1, nla_memcpy) +DUMMY(-1, nla_parse) +DUMMY(-1, nla_reserve) +DUMMY(-1, nla_strcmp) +DUMMY(-1, nla_strlcpy) +DUMMY(-1, nla_validate) +DUMMY(-1, notifier_from_errno) +DUMMY(-1, ns_capable) +DUMMY(-1, num_online_cpus) +DUMMY(-1, on_each_cpu) +DUMMY(-1, open_softirq) +DUMMY(-1, PageHighMem) +DUMMY(-1, percpu_counter_destroy) +DUMMY(-1, percpu_counter_sum_positive) +DUMMY(-1, pid_vnr) +DUMMY(-1, pr_crit) +DUMMY(-1, pr_err_once) +DUMMY(-1, preempt_disable) +DUMMY(-1, preempt_enable) +DUMMY(-1, prefetch) +DUMMY(-1, pr_emerg) +DUMMY(-1, prepare_to_wait) +DUMMY(-1, prepare_to_wait_exclusive) +DUMMY(-1, pr_err) +DUMMY(-1, pr_info) +DUMMY(-1, pr_info_once) +DUMMY(-1, pr_warn) +DUMMY(-1, put_cmsg) +DUMMY(-1, put_cpu) +DUMMY(-1, put_cpu_var) +DUMMY(-1, put_cred) +DUMMY(-1, put_device) +DUMMY(-1, put_pid) +DUMMY(-1, put_unaligned_be32) +DUMMY(-1, __raise_softirq_irqoff) +DUMMY(-1, raise_softirq_irqoff) +DUMMY(-1, random32) +DUMMY(-1, __ratelimit) +DUMMY(-1, raw_notifier_chain_unregister) +DUMMY(-1, rcu_barrier) +DUMMY(-1, register_gifconf) +DUMMY(-1, release_net) +DUMMY(-1, remove_proc_entry) +DUMMY(-1, remove_wait_queue) +DUMMY(-1, request_module) +DUMMY(-1, round_jiffies) +DUMMY(-1, round_jiffies_relative) +DUMMY(-1, round_jiffies_up) +DUMMY(-1, roundup_pow_of_two) +DUMMY(-1, rt_genid_bump) +DUMMY(-1, rtnetlink_init) +DUMMY(-1, __rtnl_unlock) +DUMMY(-1, schedule) +DUMMY(-1, schedule_delayed_work) +DUMMY(-1, schedule_timeout_interruptible) +DUMMY(-1, schedule_work) +DUMMY(-1, scm_destroy) +DUMMY(-1, scm_recv) +DUMMY(-1, scm_send) +DUMMY(-1, scnprintf) +DUMMY(-1, secpath_reset) +DUMMY(-1, secure_ip_id) +DUMMY(-1, secure_ipv4_port_ephemeral) +DUMMY(-1, secure_ipv6_id) +DUMMY(-1, secure_tcp_sequence_number) +DUMMY(-1, security_inet_conn_established) +DUMMY(-1, security_inet_csk_clone) +DUMMY(-1, security_netlink_send) +DUMMY(-1, security_release_secctx) +DUMMY(-1, security_req_classify_flow) +DUMMY(-1, security_secid_to_secctx) +DUMMY(-1, security_skb_classify_flow) +DUMMY(-1, security_skb_owned_by) +DUMMY(-1, security_sk_classify_flow) +DUMMY(-1, security_sk_free) +DUMMY(-1, security_socket_getpeersec_dgram) +DUMMY(-1, security_socket_getpeersec_stream) +DUMMY(-1, security_sock_graft) +DUMMY(-1, send_sigurg) +DUMMY(-1, send_sig) +DUMMY(-1, __set_bit) +DUMMY(-1, set_bit) +DUMMY(-1, __set_current_state) +DUMMY(-1, set_current_state) +DUMMY(-1, set_fs) +DUMMY(-1, sg_mark_end) +DUMMY(-1, sg_set_buf) +DUMMY(-1, sg_set_page) +DUMMY(-1, sha_transform) +DUMMY(-1, si_meminfo) +DUMMY(-1, S_ISSOCK) +DUMMY(-1, sk_attach_filter) +DUMMY(-1, sk_detach_filter) +DUMMY(-1, sk_filter_len) +DUMMY(-1, sk_filter_release_rcu) +DUMMY(-1, sk_get_filter) +DUMMY(-1, smp_mb__after_clear_bit) +DUMMY(-1, smp_mb__before_atomic_dec) +DUMMY(-1, __sock_recv_timestamp) +DUMMY(-1, __sock_recv_ts_and_drops) +DUMMY(-1, __sock_recv_wifi_status) +DUMMY(-1, sock_release) +DUMMY(-1, sock_update_classid) +DUMMY(-1, sock_update_memcg) +DUMMY(-1, sock_update_netprioidx) +DUMMY(-1, sock_wake_async) +DUMMY(-1, splice_to_pipe) +DUMMY(-1, srandom32) +DUMMY(-1, ssleep) +DUMMY(-1, static_key_enabled) +DUMMY(-1, static_key_slow_dec) +DUMMY(-1, static_key_slow_inc) +DUMMY(-1, strcat) +DUMMY(-1, strncpy_from_user) +DUMMY(-1, synchronize_rcu_expedited) +DUMMY(-1, sysctl_igmp_max_msf) +DUMMY(-1, sysctl_tcp_fastopen) +DUMMY(-1, system_wq) +DUMMY(-1, tasklet_init) +DUMMY(-1, tasklet_schedule) +DUMMY(-1, task_pid_nr) +DUMMY(-1, task_tgid_vnr) +DUMMY(-1, tcp_fastopen_cache_get) +DUMMY(-1, tcp_fastopen_cache_set) +DUMMY(-1, tcp_fastopen_cookie_gen) +DUMMY(-1, tcp_fetch_timewait_stamp) +DUMMY(-1, tcp_hdrlen) +DUMMY(-1, tcp_init_metrics) +DUMMY(-1, tcp_metrics_init) +DUMMY(-1, tcp_peer_is_proven) +DUMMY(-1, tcp_remember_stamp) +DUMMY(-1, tcp_tw_remember_stamp) +DUMMY(-1, tcp_update_metrics) +DUMMY(-1, test_and_clear_bit) +DUMMY(-1, test_and_set_bit) +DUMMY(-1, test_bit) +DUMMY(-1, textsearch_find) +DUMMY(-1, __this_cpu_read) +DUMMY(-1, trace_napi_poll) +DUMMY(-1, trace_net_dev_queue) +DUMMY(-1, trace_netif_rx) +DUMMY(-1, trace_skb_copy_datagram_iovec) +DUMMY(-1, trace_sock_exceed_buf_limit) +DUMMY(-1, trace_sock_rcvqueue_full) +DUMMY(-1, trace_udp_fail_queue_rcv_skb) +DUMMY(-1, try_module_get) +DUMMY(-1, tsk_restore_flags) +DUMMY(-1, u64_stats_fetch_begin_bh) +DUMMY(-1, u64_stats_fetch_retry_bh) +DUMMY(-1, u64_stats_update_begin) +DUMMY(-1, u64_stats_update_end) +DUMMY(-1, udplite4_register) +DUMMY(-1, uid_eq) +DUMMY(-1, vfree) +DUMMY(-1, virt_to_page) +DUMMY(-1, vlan_do_receive) +DUMMY(-1, __vlan_put_tag) +DUMMY(-1, vlan_untag) +DUMMY(-1, vzalloc) +DUMMY(-1, wake_up_interruptible) +DUMMY(-1, wake_up_interruptible_all) +DUMMY(-1, wake_up_interruptible_poll) +DUMMY(-1, wake_up_interruptible_sync_poll) +DUMMY(-1, WARN_ONCE) +DUMMY(-1, write_seqcount_begin) +DUMMY(-1, write_seqcount_end) +DUMMY(-1, xchg) +DUMMY(-1, xfrm4_policy_check_reverse) +DUMMY(-1, xfrm4_route_forward) +DUMMY(-1, xfrm4_udp_encap_rcv) +DUMMY(-1, xfrm_sk_free_policy) +DUMMY(-1, xfrm_user_policy) +DUMMY(-1, yield) +} /* extern "C" */ + diff --git a/dde_linux/src/lib/lxip/env.cc b/dde_linux/src/lib/lxip/env.cc new file mode 100644 index 000000000..3e89b7c7d --- /dev/null +++ b/dde_linux/src/lib/lxip/env.cc @@ -0,0 +1,20 @@ +/* + * \brief Global environment + * \author Stefan Kalkowski + * \date 2013-05-23 + */ + +/* + * 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 "env.h" + +Genode::Signal_receiver* Net::Env::receiver() +{ + static Genode::Signal_receiver receiver; + return &receiver; +} diff --git a/dde_linux/src/lib/lxip/include/env.h b/dde_linux/src/lib/lxip/include/env.h new file mode 100644 index 000000000..3853d8b1c --- /dev/null +++ b/dde_linux/src/lib/lxip/include/env.h @@ -0,0 +1,30 @@ +/* + * \brief Proxy-ARP environment + * \author Stefan Kalkowski + * \date 2013-05-24 + * + * A database containing all clients sorted by IP and MAC addresses. + */ + +/* + * 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. + */ + +#ifndef _SRC__SERVER__NIC_BRIDGE__ENV_H_ +#define _SRC__SERVER__NIC_BRIDGE__ENV_H_ + +#include + +namespace Net { + struct Env; +} + +struct Net::Env +{ + static Genode::Signal_receiver* receiver(); +}; + +#endif /* _SRC__SERVER__NIC_BRIDGE__ENV_H_ */ diff --git a/dde_linux/src/lib/lxip/include/init.h b/dde_linux/src/lib/lxip/include/init.h new file mode 100644 index 000000000..ec148aac0 --- /dev/null +++ b/dde_linux/src/lib/lxip/include/init.h @@ -0,0 +1,21 @@ +/** + * \brief IP stack initialization + * \author Sebastian Sumpf + * \date 2013-09-26 + */ + +/* + * 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. + */ +#ifndef _INCLUDE__INIT_H_ +#define _INCLUDE__INIT_H_ + +#ifdef __cplusplus +extern "C" +#endif +int lxip_init(void); + +#endif diff --git a/dde_linux/src/lib/lxip/include/linux/ip.h b/dde_linux/src/lib/lxip/include/linux/ip.h new file mode 100644 index 000000000..6c0629367 --- /dev/null +++ b/dde_linux/src/lib/lxip/include/linux/ip.h @@ -0,0 +1,2 @@ +#include +#include diff --git a/dde_linux/src/lib/lxip/include/linux/ipv6.h b/dde_linux/src/lib/lxip/include/linux/ipv6.h new file mode 100644 index 000000000..e86aa29be --- /dev/null +++ b/dde_linux/src/lib/lxip/include/linux/ipv6.h @@ -0,0 +1,2 @@ +#include +#include diff --git a/dde_linux/src/lib/lxip/include/linux/module.h b/dde_linux/src/lib/lxip/include/linux/module.h new file mode 100644 index 000000000..40be73444 --- /dev/null +++ b/dde_linux/src/lib/lxip/include/linux/module.h @@ -0,0 +1,3 @@ +#ifndef pr_fmt +#define pr_fmt(fmt) fmt +#endif diff --git a/dde_linux/src/lib/lxip/include/linux/netfilter_arp.h b/dde_linux/src/lib/lxip/include/linux/netfilter_arp.h new file mode 100644 index 000000000..97864e723 --- /dev/null +++ b/dde_linux/src/lib/lxip/include/linux/netfilter_arp.h @@ -0,0 +1 @@ +#include diff --git a/dde_linux/src/lib/lxip/include/linux/netfilter_ipv4.h b/dde_linux/src/lib/lxip/include/linux/netfilter_ipv4.h new file mode 100644 index 000000000..97864e723 --- /dev/null +++ b/dde_linux/src/lib/lxip/include/linux/netfilter_ipv4.h @@ -0,0 +1 @@ +#include diff --git a/dde_linux/src/lib/lxip/include/linux/sockios.h b/dde_linux/src/lib/lxip/include/linux/sockios.h new file mode 100644 index 000000000..b459fcf57 --- /dev/null +++ b/dde_linux/src/lib/lxip/include/linux/sockios.h @@ -0,0 +1,2 @@ +#include +#include diff --git a/dde_linux/src/lib/lxip/include/lx_emul.h b/dde_linux/src/lib/lxip/include/lx_emul.h new file mode 100644 index 000000000..a7ffe2f6e --- /dev/null +++ b/dde_linux/src/lib/lxip/include/lx_emul.h @@ -0,0 +1,2618 @@ + /* + * \brief Emulation of the Linux kernel API + * \author Sebastian Sumpf + * \date 2013-08-19 + * + * The content of this file, in particular data structures, is partially + * derived from Linux-internal headers. + */ + +/* + * 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 _LX_EMUL_H_ +#define _LX_EMUL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#include +#include +#include + +#define DEBUG_PRINTK 1 +#define DEBUG_SLAB 0 +#define DEBUG_TIMER 0 +#define DEBUG_CONG 0 +#define DEBUG_LEVEL 0 + + +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#define LINUX_VERSION_CODE KERNEL_VERSION(3,9,0) + +#define KBUILD_MODNAME "mod-noname" + + +/*************** + ** asm/bug.h ** + ***************/ + +#define WARN_ON(condition) ({ \ + int ret = !!(condition); \ + if (ret) dde_kit_printf("[%s] WARN_ON(" #condition ")\n", __func__); \ + ret; }) + +#define WARN(condition, format, ...) ({ \ + int ret = !!(condition); \ + if (ret) dde_kit_printf("[%s] WARN(" #condition ") " format "\n" , __func__, __VA_ARGS__); \ + ret; }) + +#define WARN_ON_ONCE WARN_ON + +#define BUG() do { \ + dde_kit_debug("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \ + while (1); \ +} while (0) + +#define BUG_ON(condition) do { if (condition) BUG(); } while(0) + + +/******************************* + ** linux/errno.h and friends ** + *******************************/ + +/** + * Error codes + * + * Note that the codes do not correspond to those of the Linux kernel. + */ +enum { + /* + * The following numbers correspond to FreeBSD + */ + EPERM = 1, + ENOENT = 2, + ESRCH = 3, + EINTR = 4, + EIO = 5, + ENXIO = 6, + E2BIG = 7, + ENOMEM = 12, + EACCES = 13, + EFAULT = 14, + EBUSY = 16, + EEXIST = 17, + EXDEV = 18, + ENODEV = 19, + EINVAL = 22, + ENFILE = 23, + EFBIG = 27, + ESPIPE = 29, + EPIPE = 32, + EDOM = 33, + ERANGE = 34, + EAGAIN = 35, + EINPROGRESS = 36, + EALREADY = 37, + ENOTSOCK = 38, + EDESTADDRREQ = 39, + EMSGSIZE = 40, + ENOPROTOOPT = 42, + EPROTONOSUPPORT = 43, + ESOCKTNOSUPPORT = 44, + EOPNOTSUPP = 45, + EPFNOSUPPORT = 46, + EAFNOSUPPORT = 47, + EADDRINUSE = 48, + EADDRNOTAVAIL = 49, + ENETDOWN = 50, + ENETUNREACH = 51, + ECONNABORTED = 53, + ECONNRESET = 54, + ENOBUFS = 55, + EISCONN = 56, + ENOTCONN = 57, + ETIMEDOUT = 60, + ECONNREFUSED = 61, + EHOSTDOWN = 64, + EHOSTUNREACH = 65, + ENOSYS = 78, + ENOMSG = 83, + EPROTO = 92, + EOVERFLOW = 84, + + /* + * The following numbers correspond to nothing + */ + EREMOTEIO = 200, + ERESTARTSYS = 201, + ENODATA = 202, + ETOOSMALL = 203, + ENOIOCTLCMD = 204, + ENONET = 205, + + MAX_ERRNO = 4095, +}; + + +/********************** + ** linux/compiler.h ** + **********************/ + +#define likely +#define unlikely + +#define __user +#define __rcu +#define __percpu +#define __must_check +#define __force + +#define __releases(x) +#define __acquires(x) + +#define __aligned(x) __attribute__((aligned(x))) + +#define noinline_for_stack +#define noinline __attribute__((noinline)) + +#define __printf(a, b) __attribute__((format(printf, a, b))) +#define __attribute_const__ __attribute__((__const__)) + +#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) + +#define __HAVE_BUILTIN_BSWAP32__ +#define __HAVE_BUILTIN_BSWAP64__ + + +/****************** + ** linux/init.h ** + ******************/ + +#define __init +#define __initdata +#define __exit + +#define _SETUP_CONCAT(a, b) __##a##b +#define SETUP_CONCAT(a, b) _SETUP_CONCAT(a, b) +#define __setup(str, fn) void SETUP_CONCAT(fn, SETUP_SUFFIX)(void *addrs) { fn(addrs); } + +/* these must be called by us during initialization */ +#define core_initcall(fn) void core_##fn(void) { fn(); } +#define subsys_initcall(fn) void subsys_##fn(void) { fn(); } +#define fs_initcall(fn) void fs_##fn(void) { fn(); } +#define late_initcall(fn) void late_##fn(void) { fn(); } + + +/******************** + ** linux/module.h ** + ********************/ + +#define EXPORT_SYMBOL(x) +#define EXPORT_SYMBOL_GPL(x) +#define MODULE_LICENSE(x) +#define MODULE_NAME_LEN (64 - sizeof(long)) +#define MODULE_ALIAS(name) +#define MODULE_AUTHOR(name) +#define MODULE_DESCRIPTION(desc) +#define MODULE_VERSION(version) +#define THIS_MODULE 0 + + +struct module; +#define module_init(fn) void module_##fn(void) { fn(); } +#define module_exit(fn) void module_exit_##fn(void) { exit_fn(); } + + +/************************* + ** linux/moduleparam.h ** + *************************/ + +#define module_param(name, type, perm) +#define MODULE_PARM_DESC(_parm, desc) + + +/********************* + ** linux/kconfig.h ** + *********************/ + +#define IS_ENABLED(x) x +#define CONFIG_DEFAULT_TCP_CONG "cubic" + + +/*************** + ** asm/bug.h ** + ***************/ + +#define BUG() do { \ + dde_kit_debug("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \ + while (1); \ +} while (0) + + +/******************* + ** linux/types.h ** + *******************/ + +typedef dde_kit_int8_t int8_t; +typedef dde_kit_int16_t int16_t; +typedef dde_kit_int32_t int32_t; +typedef dde_kit_int64_t int64_t; + +typedef dde_kit_uint8_t uint8_t; +typedef dde_kit_uint16_t uint16_t; +typedef dde_kit_uint32_t uint32_t; +typedef dde_kit_uint64_t uint64_t; +typedef dde_kit_size_t size_t; + +typedef uint32_t uint; + +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef uint8_t __u8; +typedef uint16_t __u16; +typedef uint32_t __u32; +typedef uint64_t __u64; + + +typedef int16_t __s16; +typedef int32_t __s32; + +typedef __u16 __le16; +typedef __u32 __le32; +typedef __u64 __le64; + +typedef __u16 __be16; +typedef __u32 __be32; +typedef __u64 __be64; + +typedef __u16 __sum16; +typedef __u32 __wsum; + +typedef unsigned gfp_t; +typedef unsigned long dma_addr_t; +typedef long long loff_t; +typedef size_t __kernel_size_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef int pid_t; +typedef long ssize_t; +typedef unsigned short umode_t; + +#define __aligned_u64 __u64 __attribute__((aligned(8))) + +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, 8 * sizeof(long)) +#define DECLARE_BITMAP(name,bits) \ + unsigned long name[BITS_TO_LONGS(bits)] + +struct list_head { + struct list_head *next, *prev; +}; + +struct hlist_head { + struct hlist_node *first; +}; + +struct hlist_node { + struct hlist_node *next, **pprev; +}; + +#ifndef __cplusplus +typedef int bool; +enum { true = 1, false = 0 }; +#endif /* __cplusplus */ + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif /* __cplusplus */ +#endif /* NULL */ + +#define __bitwise + + +/******************************* + ** uapi/asm-generic/signal.h ** + *******************************/ + +enum { SIGPIPE }; + +/******************** + ** linux/bitmap.h ** + ********************/ + +void bitmap_fill(unsigned long *dst, int nbits); +void bitmap_zero(unsigned long *dst, int nbits); + + +/******************* + ** linux/ctype.h ** + *******************/ + +#define __ismask(x) (_ctype[(int)(unsigned char)(x)]) +#define isspace(c) ((unsigned char)c == 0x20U) + +/***************** + ** linux/err.h ** + *****************/ + +#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) + +static inline bool IS_ERR(void const *ptr) { + return (unsigned long)(ptr) > (unsigned long)(-1000); } + +static inline void * ERR_PTR(long error) { + return (void *) error; +} + +static inline long IS_ERR_OR_NULL(const void *ptr) { + return !ptr || IS_ERR_VALUE((unsigned long)ptr); } + +static inline long PTR_ERR(const void *ptr) { return (long) ptr; } + + +/******************************* + ** asm-generic/scatterlist.h ** + *******************************/ + +struct scatterlist +{ +}; + +/******************** + ** linux/printk.h ** + ********************/ + +#define KERN_WARNING "<4>" + +#define pr_crit(fmt, ...) printk(KERN_CRIT fmt, ##__VA_ARGS__) +#define pr_info(fmt, ...) printk(KERN_INFO fmt, ##__VA_ARGS__) +#define pr_err(fmt, ...) printk(KERN_ERR fmt, ##__VA_ARGS__) +#define pr_notice(fmt, ...) printk(KERN_NOTICE fmt, ##__VA_ARGS__) +#define pr_cont(fmt, ...) printk(KERN_CONT fmt, ##__VA_ARGS__) + +#if DEBUG_LEVEL +#define pr_debug(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__) +#else +#define pr_debug(fmt, ...) +#endif + +struct va_format +{ + const char *fmt; + va_list *va; +}; + +static inline int _printk(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + dde_kit_vprintf(fmt, args); + va_end(args); + return 0; +} + +#if DEBUG_PRINTK +#define printk _printk +#define vprintk dde_kit_vprintf +#define panic dde_kit_panic +#else +#define printk(...) +#define vprintk(...) +#define panic(...) +#endif + + +/****************** + ** linux/hash.h ** + ******************/ + +u32 hash_32(u32 val, unsigned int bits); + + +/**************************************************************** + ** arch/(*)/include/asm/(processor.h|segment.h|thread_info.h) ** + ****************************************************************/ + +typedef unsigned long mm_segment_t; + + +/************************************* + ** linux/byteorder/little_endian.h ** + *************************************/ + +#include + + +/******************************* + ** linux/byteorder/generic.h ** + *******************************/ + +#define cpu_to_be16 __cpu_to_be16 +#define cpu_to_be32 __cpu_to_be32 + +#define be16_to_cpup __be16_to_cpup +#define be32_to_cpup __be32_to_cpup + +#define htons(x) __cpu_to_be16(x) +#define ntohs(x) __be16_to_cpu(x) +#define htonl(x) __cpu_to_be32(x) +#define ntohl(x) __be32_to_cpu(x) + + +/********************************* + ** linux/unaligned/access_ok.h ** + *********************************/ + +static inline u16 get_unaligned_be16(const void *p) +{ + return be16_to_cpup((__be16 *)p); +} + +static inline u32 get_unaligned_be32(const void *p) +{ + return be32_to_cpup((__be32 *)p); +} + + +/***************** + ** asm/param.h ** + *****************/ + +#define HZ 100UL + + +/********************* + ** linux/stringify ** + *********************/ + +#define __stringify_1(x...) #x +#define __stringify(x...) __stringify_1(x) + + +/******************** + ** linux/kernel.h ** + ********************/ + +#define KERN_DEBUG "DEBUG: " +#define KERN_INFO "INFO: " +#define KERN_ERR "ERROR: " +#define KERN_CRIT "CRTITCAL: " +#define KERN_NOTICE "NOTICE: " +#define KERN_EMERG "EMERG: " +#define KERN_ALERT "ALERT: " +#define KERN_CONT "" + + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +/* normally provided by linux/stddef.h, needed by linux/list.h */ +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) + +#define ALIGN(x, a) x +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +#define USHRT_MAX ((u16)(~0U)) +#define INT_MAX ((int)(~0U>>1)) +#define INT_MIN (-INT_MAX - 1) +#define UINT_MAX (~0U) + +static inline size_t min(size_t a, size_t b) { + return a < b ? a : b; } + +#define max(x, y) ({ \ + typeof(x) _max1 = (x); \ + typeof(y) _max2 = (y); \ + (void) (&_max1 == &_max2); \ + _max1 > _max2 ? _max1 : _max2; }) + +#define min_t(type, x, y) ({ \ + type __min1 = (x); \ + type __min2 = (y); \ + __min1 < __min2 ? __min1: __min2; }) + +#define max_t(type, x, y) ({ \ + type __max1 = (x); \ + type __max2 = (y); \ + __max1 > __max2 ? __max1: __max2; }) + +#define swap(a, b) ({ \ + typeof(a) __tmp = (a); \ + (a) = (b); \ + (b) = __tmp; }) + +#define PTR_ALIGN(p, a) ({ \ + unsigned long _p = (unsigned long)p; \ + _p = (_p + a - 1) & ~(a - 1); \ + p = (typeof(p))_p; \ + p; \ +}) + +#define BUILD_BUG_ON(condition) + +#define _RET_IP_ (unsigned long)__builtin_return_address(0) + +void might_sleep(); +#define might_sleep_if(cond) do { if (cond) might_sleep(); } while (0) + +enum { SPRINTF_STR_LEN = 64 }; + +int snprintf(char *buf, size_t size, const char *fmt, ...); +int sprintf(char *buf, const char *fmt, ...); +int sscanf(const char *, const char *, ...); + +#define sprintf(buf, fmt, ...) snprintf(buf, SPRINTF_STR_LEN, fmt, __VA_ARGS__) + +#define kasprintf(gfp, fmt, ...) ({ \ + void *buf = kmalloc(SPRINTF_STR_LEN, 0); \ + sprintf(buf, fmt, __VA_ARGS__); \ + buf; \ +}) + +//char *kasprintf(gfp_t gfp, const char *fmt, ...); + +char *get_options(const char *str, int nints, int *ints); + +/************************** + ** uapi/linux/sysinfo.h ** + **************************/ + +struct sysinfo +{ + unsigned long totalram; +}; + + +/******************* + ** asm/cmpxchg.h ** + *******************/ + +#define cmpxchg(ptr, o, n) ({ \ + typeof(*ptr) prev = *ptr; \ + *ptr = (*ptr == o) ? n : *ptr; \ + prev;\ +}) + + +/****************** + ** asm/atomic.h ** + ******************/ + +#define ATOMIC_INIT(i) { (i) } + +typedef struct atomic { unsigned long counter; } atomic_t; +typedef atomic_t atomic_long_t; + +static inline unsigned int atomic_read(const atomic_t *p) { return p->counter; } +static inline void atomic_set(atomic_t *p, int i) { p->counter = i; } +static inline void atomic_sub(int i, atomic_t *p) { p->counter -= i; } +static inline int atomic_sub_return(int i, atomic_t *p) { p->counter -= i; return p->counter; } +static inline int atomic_sub_and_test(int i, atomic_t *p) { return atomic_sub_return(i, p) == 0; } + +static inline int atomic_dec_return(atomic_t *p) { return atomic_sub_return(1, p); } +static inline int atomic_dec_and_test(atomic_t *p) { return atomic_sub_return(1, p) == 0; } +static inline void atomic_dec(atomic_t *p) { atomic_sub_return(1, p); } + + +static inline void atomic_inc(atomic_t *p) { p->counter++; } +static inline int atomic_inc_return(atomic_t *p) { return p->counter++; } +static inline int atomic_inc_not_zero(atomic_t *p) { return p->counter ? p->counter++ : 0; } + +static inline void atomic_add(int i, atomic_t *p) { p->counter += i; } + + +static inline void atomic_long_inc(atomic_long_t *p) { p->counter++; } +static inline void atomic_long_sub(int i, atomic_long_t *p) { atomic_sub(i, p); } +static inline long atomic_long_add_return(long i, atomic_long_t *p) { + atomic_add(i, p); return p->counter; } +static inline long atomic_long_read(atomic_long_t *p) { return (long)atomic_read(p); } + +static inline int atomic_cmpxchg(atomic_t *v, int old, int n) +{ + return cmpxchg(&v->counter, old, n); +} + + +static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint) +{ + int val, c = hint; + + /* sanity test, should be removed by compiler if hint is a constant */ + if (!hint) + return atomic_inc_not_zero(v); + + do { + val = atomic_cmpxchg(v, c, c + 1); + if (val == c) + return 1; + c = val; + } while (c); + + return 0; +} + +static inline int atomic_add_unless(atomic_t *v, int a, int u) +{ + int ret; + unsigned long flags; + + ret = v->counter; + if (ret != u) + v->counter += a; + + return ret != u; +} + +/****************** + ** linux/kref.h ** + ******************/ + +struct kref { atomic_t refcount; }; + + +/******************** + ** linux/uidgid.h ** + ********************/ + +typedef unsigned kuid_t; +typedef unsigned kgid_t; + +#define GLOBAL_ROOT_UID (kuid_t)0 + +/*********************** + ** linux/kmemcheck.h ** + ***********************/ + +#define kmemcheck_bitfield_begin(name) +#define kmemcheck_bitfield_end(name) +#define kmemcheck_annotate_bitfield(ptr, name) + +/************************* + ** asm-generic/div64.h ** + *************************/ + +#define do_div(n,base) ({ \ + unsigned long __base = (base); \ + unsigned long __rem; \ + __rem = ((uint64_t)(n)) % __base; \ + (n) = ((uint64_t)(n)) / __base; \ + __rem; \ +}) +/************************* + ** asm-generic/cache.h ** + *************************/ + +enum { + L1_CACHE_BYTES = 32, //XXX is 64 for CA15 */ + SMP_CACHE_BYTES = L1_CACHE_BYTES, +}; + +#define ____cacheline_aligned_in_smp +#define ____cacheline_aligned + + +/******************** + ** linux/dcache.h ** + ********************/ + +#define __read_mostly +unsigned int full_name_hash(const unsigned char *, unsigned int); + +/****************** + ** linux/numa.h ** + ******************/ + +enum { NUMA_NO_NODE = -1 }; + + +/************************ + ** linux/jump_label.h ** + ************************/ + +struct static_key { }; +#define STATIC_KEY_INIT_FALSE ((struct static_key) {}) + +/******************** + ** linux/poison.h ** + ********************/ + +/* + * In list.h, LIST_POISON1 and LIST_POISON2 are assigned to 'struct list_head + * *' as well as 'struct hlist_node *' pointers. Consequently, C++ compiler + * produces an error "cannot convert... in assignment". To compile 'list.h' + * included by C++ source code, we have to define these macros to the only + * value universally accepted for pointer assigments.h + */ + +#ifdef __cplusplus +#define LIST_POISON1 0 +#define LIST_POISON2 0 +#else +#define LIST_POISON1 ((void *)0x00100100) +#define LIST_POISON2 ((void *)0x00200200) +#endif /* __cplusplus */ + +/********************************** + ** linux/bitops.h, asm/bitops.h ** + **********************************/ + +enum { BITS_PER_LONG = sizeof(long) * 8 }; +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) + +#include + +#define test_and_clear_bit(nr, addr) \ + __test_and_clear_bit(nr, (volatile unsigned long *)(addr)) +#define test_and_set_bit(nr, addr) \ + __test_and_set_bit(nr, (volatile unsigned long *)(addr)) +#define set_bit(nr, addr) \ + __set_bit(nr, (volatile unsigned long *)(addr)) +#define clear_bit(nr, addr) \ + __clear_bit(nr, (volatile unsigned long *)(addr)) + +#define smp_mb__before_clear_bit() + +static int get_bitmask_order(unsigned int count) { + return __builtin_clz(count) ^ 0x1f; } + + +#define ffs(x) __builtin_ffs(x) +#define ffz(x) ffs(~(x)) + +static inline __u32 rol32(__u32 word, unsigned int shift) +{ + return (word << shift) | (word >> (32 - shift)); +} + + +/******************************* + ** asm-generic/bitops/find.h ** + *******************************/ + +unsigned long find_first_zero_bit(unsigned long const *addr, unsigned long size); + + +/**************************** + ** asm-generic/getorder.h ** + ****************************/ + +int get_order(unsigned long size); + + +/****************** + ** linux/log2.h ** + ******************/ + +unsigned long ilog2(unsigned long n); + +#define roundup_pow_of_two(n) ( \ + 1UL << (ilog2((n) - 1) + 1)) + + +/**************** + ** asm/page.h ** + ****************/ + +/* + * For now, hardcoded + */ +#define PAGE_SIZE 4096 + +enum { + PAGE_SHIFT = 12, +}; + +#ifdef __cplusplus +#define private priv +#endif +struct page +{ + int pfmemalloc; + int mapping; + atomic_t _count; + void *addr; + unsigned long private; +#ifdef __cplusplus +#undef priv +#endif +} __attribute((packed)); + + +/************************* + ** linux/res_counter.h ** + *************************/ + +enum { RES_USAGE }; + + +/************************ + ** linux/memcontrol.h ** + ************************/ + +enum { UNDER_LIMIT, SOFT_LIMIT, OVER_LIMIT }; + + +/********************* + ** mm/memcontrol.c ** + *********************/ + +struct mem_cgroup; + + +/********************** + ** linux/mm-types.h ** + **********************/ + +struct page_frag +{ + struct page *page; + __u16 offset; + __u16 size; +}; + + +/**************** + ** linux/mm.h ** + ****************/ + +extern unsigned long totalram_pages; +extern unsigned long num_physpages; + +static inline struct page *compound_head(struct page *page) { return page; } +static inline void *page_address(struct page *page) { return page->addr; }; + +void get_page(struct page *page); +void put_page(struct page *page); + +struct page *virt_to_head_page(const void *x); +struct page *virt_to_page(const void *x); + + +/****************** + ** linux/swap.h ** + ******************/ + +unsigned long nr_free_buffer_pages(void); + + + +/***************** + ** linux/gfp.h ** + *****************/ + +enum { + __GFP_DMA = 0x01u, + __GFP_WAIT = 0x10u, + __GFP_COLD = 0x100u, + __GFP_NOWARN = 0x200u, + __GFP_REPEAT = 0x400u, + __GFP_MEMALLOC = 0x2000u, + __GFP_ZERO = 0x8000u, + __GFP_COMP = 0x4000u, + __GFP_NOMEMALLOC = 0x10000u, +}; + +enum { + GFP_DMA = __GFP_DMA, + GFP_KERNEL = 0x0u, + GFP_USER = 0x1u, + GFP_ATOMIC = 0x20u, +}; + +struct page *alloc_pages_node(int nid, gfp_t gfp_mask, + unsigned int order); + +struct page *alloc_pages(gfp_t gfp_mask, unsigned int order); + +#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) + +unsigned long get_zeroed_page(gfp_t gfp_mask); +#define free_page(p) kfree((void *)p) + +/****************** + ** linux/slab.h ** + ******************/ + +enum { + SLAB_HWCACHE_ALIGN = 0x2000, + SLAB_PANIC = 0x40000, + SLAB_DESTROY_BY_RCU = 0x80000, + /* set to 1M, increase if necessary */ + KMALLOC_MAX_SIZE = 1 << 20, +}; + +void *kmalloc(size_t size, gfp_t flags); +void *kzalloc(size_t size, gfp_t flags); +void *kcalloc(size_t n, size_t size, gfp_t flags); +void *krealloc(const void *, size_t, gfp_t); +void *kzalloc_node(size_t size, gfp_t flags, int node); +void *kmalloc_node_track_caller(size_t size, gfp_t flags, int node); +void kfree(const void *); +size_t ksize(const void *objp); + +struct kmem_cache; + +struct kmem_cache *kmem_cache_create(const char *, size_t, size_t, + unsigned long, void (*)(void *)); +void *kmem_cache_alloc(struct kmem_cache *, gfp_t); +void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); + +void kmem_cache_free(struct kmem_cache *cache, void *objp); + + +/********************* + ** linux/vmalloc.h ** + *********************/ + +void *vzalloc(unsigned long size); + + +/********************** + ** linux/highmem.h ** + **********************/ + +static inline void *kmap(struct page *page) { return page_address(page); } +static inline void *kmap_atomic(struct page *page) { return kmap(page); } + + +/********************* + ** linux/bootmem.h ** + *********************/ + +void *alloc_large_system_hash(const char *tablename, + unsigned long bucketsize, + unsigned long numentries, + int scale, + int flags, + unsigned int *_hash_shift, + unsigned int *_hash_mask, + unsigned long low_limit, + unsigned long high_limit); + + +/********************** + ** linux/spinlock.h ** + **********************/ + +typedef unsigned spinlock_t; +#define DEFINE_SPINLOCK(name) spinlock_t name = 0; +#define spin_lock_nested(lock, subclass) +static inline void spin_lock_init(spinlock_t *lock) { } + +static inline void spin_lock(spinlock_t *lock) { } +static inline void spin_unlock(spinlock_t *lock) { } + +static inline void spin_lock_bh(spinlock_t *lock) { } +static inline void spin_unlock_bh(spinlock_t *lock) { } + +int spin_trylock(spinlock_t *lock); + +/**************************** + ** linux/spinlock_types.h ** + ****************************/ + +#define __SPIN_LOCK_UNLOCKED(x) 0 + + +/******************* + ** linux/mutex.h ** + *******************/ + +struct mutex { }; + +#define DEFINE_MUTEX(n) struct mutex n; + + +/************************** + ** linux/rwlock_types.h ** + **************************/ + +typedef unsigned rwlock_t; + +#define DEFINE_RWLOCK(x) rwlock_t x; +#define __RW_LOCK_UNLOCKED(x) 0 + + +/******************* + ** linux/rwsem.h ** + *******************/ + +struct rw_semaphore { int dummy; }; + +#define __RWSEM_INITIALIZER(name) { 0 } + + +/********************* + ** linux/seqlock.h ** + *********************/ + +typedef unsigned seqlock_t; + +#define __SEQLOCK_UNLOCKED(x) 0 + +/********************* + ** linux/jiffies.h ** + *********************/ + +extern volatile unsigned long jiffies; + +enum { INITIAL_JIFFIES = 0 }; + +unsigned int jiffies_to_msecs(const unsigned long j); +unsigned long msecs_to_jiffies(const unsigned int m); + +long time_after(long a, long b); +long time_after_eq(long a, long b); + +static inline long time_before(long a, long b) { return time_after(b, a); } +static inline long time_before_eq(long a, long b) { return time_after_eq(b ,a); } + + +/****************** + ** linux/time.h ** + ******************/ + +struct timeval +{ + __kernel_time_t tv_sec; + __kernel_suseconds_t tv_usec; +}; + +struct timespec { + __kernel_time_t tv_sec; + long tv_nsec; +}; + +enum { + MSEC_PER_SEC = 1000L, + USEC_PER_SEC = MSEC_PER_SEC * 1000L, + NSEC_PER_MSEC = 1000L * 1000L, + NSEC_PER_SEC = MSEC_PER_SEC * NSEC_PER_MSEC, + USEC, + USEC_PER_MSEC = 1000L, +}; + +unsigned long get_seconds(void); + + +/******************* + ** linux/ktime.h ** + *******************/ + +union ktime { + s64 tv64; +}; + typedef union ktime ktime_t; + +struct timeval ktime_to_timeval(const ktime_t); +struct timespec ktime_to_timespec(const ktime_t kt); + +ktime_t ktime_sub(const ktime_t, const ktime_t); + +static inline ktime_t ktime_set(const long secs, const unsigned long nsecs) +{ + return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs }; +} + +static inline s64 ktime_to_ms(const ktime_t kt) +{ + return kt.tv64 / NSEC_PER_MSEC; +} + +static inline ktime_t ktime_get_real(void) +{ + return (ktime_t) { .tv64 = jiffies * (1000 / HZ) * NSEC_PER_MSEC }; +} + +/******************* + ** linux/timer.h ** + *******************/ + +struct timer_list +{ + unsigned long expires; + void (*function)(unsigned long); + unsigned long data; + void *timer; +}; + + +#define TIMER_INITIALIZER(_function, _expires, _data) { \ + .function = (_function), \ + .expires = (_expires), \ + .data = (_data), \ +} + +void init_timer(struct timer_list *timer); +void add_timer(struct timer_list *timer); +int mod_timer(struct timer_list *timer, unsigned long expires); +void setup_timer(struct timer_list *timer,void (*function)(unsigned long), + unsigned long data); +int timer_pending(const struct timer_list * timer); +int del_timer(struct timer_list *timer); + + +/********************* + ** linux/hrtimer.h ** + *********************/ + +struct hrtimer { }; + + +/******************* + ** linux/delay.h ** + *******************/ + + void msleep(unsigned int msecs); + +/*********************** + ** linux/ratelimit.h ** + ***********************/ + +struct ratelimit_state +{ + int burst; + int interval; +}; + +#define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init) \ + struct ratelimit_state name = { \ + .interval = interval_init, \ + .burst = burst_init, \ + } + + +/******************* + ** linux/sched.h ** + *******************/ + +enum { + PF_EXITING = 0x4, + PF_MEMALLOC = 0x800, + + //MAX_SCHEDULE_TIMEOUT = (~0U >> 1) + MAX_SCHEDULE_TIMEOUT = 1000, +}; + +enum { + TASK_RUNNING = 0, + TASK_INTERRUPTIBLE = 1, + TASK_UNINTERRUPTIBLE = 2, + TASK_COMM_LEN = 16, +}; + +struct task_struct +{ + unsigned int flags; + struct page_frag task_frag; + char comm[TASK_COMM_LEN]; + struct audit_context *audit_context; +}; + +/* normally defined in asm/current.h, included by sched.h */ +extern struct task_struct *current; + +long schedule_timeout_uninterruptible(signed long timeout); +signed long schedule_timeout(signed long timeout); + +/************************ + ** linux/textsearch.h ** + ************************/ + +struct ts_state +{ + char cb[40]; +}; + +struct ts_config +{ + unsigned int (*get_next_block)(unsigned int consumed, + const u8 **dst, + struct ts_config *conf, + struct ts_state *state); + void (*finish)(struct ts_config *conf, + struct ts_state *state); +}; + + +/**************************** + ** linux/rcu_list_nulls.h ** + ****************************/ + +#include + +#define hlist_nulls_add_head_rcu hlist_nulls_add_head + +static inline void hlist_nulls_del_init_rcu(struct hlist_nulls_node *n) +{ + if (!hlist_nulls_unhashed(n)) { + __hlist_nulls_del(n); + n->pprev = NULL; + } +} + + +/********************* + ** linux/lockdep.h ** + *********************/ + +enum { + SINGLE_DEPTH_NESTING = 1, +}; + +#define lockdep_set_class(lock, key) + +struct lock_class_key { }; +struct lockdep_map { }; + + +/***************** + ** linux/smp.h ** + *****************/ + +#define smp_processor_id() 0 + +/********************** + ** linux/rcupdate.h ** + **********************/ + +struct rcu_head { }; + +#define kfree_rcu(ptr, offset) kfree(ptr) + +#define rcu_dereference(p) p +#define rcu_dereference_bh(p) p +#define rcu_dereference_check(p, c) p +#define rcu_dereference_protected(p, c) p +#define rcu_dereference_raw(p) p +#define rcu_dereference_rtnl(p) p +#define rcu_dereference_index_check(p, c) p + +#define rcu_assign_pointer(p, v) p = v; +#define rcu_access_pointer(p) p + +void rcu_read_lock(void); +void rcu_read_unlock(void); + +static inline int rcu_read_lock_held(void) { return 1; } +static inline int rcu_read_lock_bh_held(void) { return 1; } + +static inline void call_rcu(struct rcu_head *head, + void (*func)(struct rcu_head *head)) +{ func(head); } + +#define RCU_INIT_POINTER(p, v) p = (typeof(*v) *)v + +/********************* + ** linux/rculist.h ** + *********************/ + +#define hlist_for_each_entry_rcu(pos, head, member) \ + hlist_for_each_entry(pos, head, member) + +#define list_next_rcu(list) (*((struct list_head **)(&(list)->next))) + +#define list_for_each_entry_rcu(pos, head, member) \ + list_for_each_entry(pos, head, member) + +#define list_first_or_null_rcu(ptr, type, member) ({ \ + struct list_head *__ptr = (ptr); \ + struct list_head __rcu *__next = list_next_rcu(__ptr); \ + __ptr != __next ? container_of(__next, type, member) : NULL; \ +}) + +#define list_add_rcu list_add +#define list_add_tail_rcu list_add_tail +#define hlist_add_head_rcu hlist_add_head + +#define list_del_rcu list_del +#define hlist_del_rcu hlist_del + +#define hlist_del_init_rcu hlist_del_init + +#define free_percpu(pdata) kfree(pdata) + + +/*************************** + ** linux/rculist_nulls.h ** + ***************************/ + +#define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member) \ + hlist_nulls_for_each_entry(tpos, pos, head, member) + + +/************************* + ** linux/percpu-defs.h ** + *************************/ + +#define DECLARE_PER_CPU_ALIGNED(type, name) \ + extern typeof(type) name + +#define DEFINE_PER_CPU_ALIGNED(type, name) \ + typeof(type) name + +#define DEFINE_PER_CPU(type, name) \ + typeof(type) name + +#define EXPORT_PER_CPU_SYMBOL(x) + +/******************** + ** linux/percpu.h ** + ********************/ + +void *__alloc_percpu(size_t size, size_t align); + +#define alloc_percpu(type) \ + (typeof(type) __percpu *)__alloc_percpu(sizeof(type), __alignof__(type)) + +#define per_cpu(var, cpu) var +#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu);(typeof(*(ptr)) *)(ptr); }) +#define get_cpu_var(var) var +#define __get_cpu_var(var) var +#define __this_cpu_ptr(ptr) per_cpu_ptr(ptr, 0) +#define this_cpu_ptr(ptr) per_cpu_ptr(ptr, 0) + +#define this_cpu_inc(pcp) pcp += 1 +#define this_cpu_dec(pcp) pcp -= 1 + +#define __this_cpu_inc(pcp) this_cpu_inc(pcp) +#define __this_cpu_dec(pcp) this_cpu_dec(pcp) + +#define this_cpu_add(pcp, val) pcp += val +#define __this_cpu_add(pcp, val) this_cpu_add(pcp, val) +#define get_cpu() 0 + + +/**************************** + ** linux/percpu_counter.h ** + ****************************/ + +struct percpu_counter +{ + s64 count; +}; + +static inline int percpu_counter_init(struct percpu_counter *fbc, s64 amount) +{ + fbc->count = amount; + return 0; +} + +static inline s64 percpu_counter_read(struct percpu_counter *fbc) +{ + return fbc->count; +} + +static inline +void percpu_counter_add(struct percpu_counter *fbc, s64 amount) +{ + fbc->count += amount; +} + +static inline +void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch) +{ + percpu_counter_add(fbc, amount); +} + +s64 percpu_counter_sum_positive(struct percpu_counter *fbc); + +static inline void percpu_counter_inc(struct percpu_counter *fbc) +{ + percpu_counter_add(fbc, 1); +} + +static inline void percpu_counter_dec(struct percpu_counter *fbc) +{ + percpu_counter_add(fbc, -1); +} + +static inline +s64 percpu_counter_read_positive(struct percpu_counter *fbc) +{ + return fbc->count; +} + +void percpu_counter_destroy(struct percpu_counter *fbc); + +/***************** + ** linux/cpu.h ** + *****************/ + +enum { + CPU_DEAD = 0x7, + CPU_TASKS_FROZEN = 0x10, + CPU_DEAD_FROZEN = CPU_DEAD | CPU_TASKS_FROZEN, +}; + + +/********************* + ** linux/cpumask.h ** + *********************/ + +extern const struct cpumask *const cpu_possible_mask; + +#define nr_cpu_ids 1 + +#define for_each_cpu(cpu, mask) \ + for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) + +#define for_each_possible_cpu(cpu) for_each_cpu((cpu), cpu_possible_mask) + + +/********************* + ** linux/kobject.h ** + *********************/ + +enum kobject_action +{ + KOBJ_ADD, + KOBJ_REMOVE, +}; + +struct kobject { }; + + +/*********************** + ** linux/interrupt.h ** + ***********************/ + +enum { + NET_TX_SOFTIRQ, + NET_RX_SOFTIRQ, + NET_SOFTIRQS, +}; + +struct softirq_action { }; + + +/************************* + ** linux/bottom_half.h ** + *************************/ + +void local_bh_disable(void); +void local_bh_enable(void); + + +/******************** + ** linux/string.h ** + ********************/ + +int memcmp(const void *, const void *, size_t); +void *memmove(void *, const void *, size_t); +void *memset(void *s, int c, size_t n); +void *kmemdup(const void *src, size_t len, gfp_t gfp); +char *kstrdup(const char *s, gfp_t gfp); +char *strchr(const char *, int); +size_t strnlen(const char *s, size_t maxlen); +size_t strlen(const char *); +char *strnchr(const char *, size_t, int); +char *strcat(char *dest, const char *src); +int strcmp(const char *, const char *); +int strncmp(const char *, const char *, size_t); +char *strcpy(char *to, const char *from); +char * strncpy(char *,const char *, __kernel_size_t);; +size_t strlcpy(char *dest, const char *src, size_t size); +char * strsep(char **,const char *); + +void *genode_memcpy(void *d, const void *s, size_t n); +static inline void *memcpy(void *d, const void *s, size_t n) { + return genode_memcpy(d, s, n); } + + +/*************************** + ** asm-generic/uaccess.h ** + ***************************/ + +enum { VERIFY_READ = 0 }; + +static inline +long copy_from_user(void *to, const void *from, unsigned long n) +{ + memcpy(to, from, n); + return 0; +} + +static inline +long copy_to_user(void *to, const void *from, unsigned long n) +{ + memcpy(to, from, n); + return 0; +} + + +#define get_user(src, dst) ({ \ + src = *dst; \ + 0; }) + +#define put_user(x, ptr) ({ \ + *ptr = x; \ + 0; }) + +#define __copy_from_user copy_from_user + + +/***************************** + ** uapi/linux/capability.h ** + *****************************/ + +enum { + CAP_NET_BIND_SERVICE = 10, + CAP_NET_ADMIN = 12, + CAP_NET_RAW = 13, +}; + + +/******************** + ** linux/sysctl.h ** + ********************/ + +struct ctl_table; + +typedef int proc_handler (struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); + + +/************************ + ** fs/proc/internal.h ** + ************************/ + +struct proc_dir_entry { }; + + +/********************************* + ** uapi/asm-generic/siginfo..h ** + *********************************/ + +enum +{ + POLL_IN = 1, + POLL_OUT = 2, + POLL_ERR = 4, + POLL_PRI = 5, + POLL_HUP = 6, +}; + +/******************** + ** linux/pm_qos.h ** + ********************/ + +struct pm_qos_request { }; + +/********************************* + ** (uapi|linux|kernel)/audit.h ** + *********************************/ + +enum { + AUDIT_ANOM_PROMISCUOUS = 1700, +}; + +extern int audit_enabled; + +struct audit_context { }; + + +/******************** + ** linux/device.h ** + ********************/ + +struct device_driver +{ + char const *name; +}; + + +struct device +{ + struct kobject *kobj; + struct device *parent; + struct device_driver *driver; +}; + +struct class_attribute { }; + +const char *dev_driver_string(const struct device *dev); +const char *dev_name(const struct device *dev); + +/************************* + ** linux/dma-direction ** + *************************/ + +enum dma_data_direction { D = 1}; + + +/************************* + ** linux/dma-mapping.h ** + *************************/ + +dma_addr_t dma_map_page(struct device *dev, struct page *page, + size_t offset, size_t size, + enum dma_data_direction dir); + + +/***************** + ** linux/phy.h ** + *****************/ + +struct ethtool_ts_info; +struct phy_device; + +struct phy_driver +{ + int (*ts_info)(struct phy_device *phydev, struct ethtool_ts_info *ti); +}; + +struct phy_device +{ + struct phy_driver *drv; +}; + +/***************************** + ** uapi/asm-generic/poll.h ** + *****************************/ + +enum { + POLLIN = 0x1, + POLLPRI = 0x2, + POLLOUT = 0x4, + POLLERR = 0x8, + POLLHUP = 0x10, + POLLRDNORM = 0x40, + POLLRDBAND = 0x80, + POLLWRNORM = 0x100, + POLLWRBAND = 0x200, + POLLRDHUP = 0x2000, +}; + + +/****************** + ** linux/wait.h ** + ******************/ + +typedef struct wait_queue_head { int dummy; } wait_queue_head_t; +typedef struct wait_queue { } wait_queue_t; + +#define DEFINE_WAIT(name) \ + wait_queue_t name; + +#define __WAIT_QUEUE_HEAD_INITIALIZER(name) { 0 } + +#define DECLARE_WAITQUEUE(name, tsk) \ + wait_queue_t name + +#define DECLARE_WAIT_QUEUE_HEAD(name) \ + wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) + +#define DEFINE_WAIT_FUNC(name, function) \ + wait_queue_t name + +/****************** + ** linux/poll.h ** + ******************/ + +typedef struct poll_table_struct { } poll_table; + +struct file; +void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p); + +/**************************** + ** linux/user_namespace.h ** + ****************************/ + +struct user_namespace { }; + +/****************** + ** linux/cred.h ** + ******************/ + +enum { + NGROUPS_PER_BLOCK = PAGE_SIZE / sizeof(kgid_t) +}; + +struct cred +{ + struct user_namespace *user_ns; + kuid_t euid; + kgid_t egid; +}; + +struct group_info +{ + int ngroups; + int nblocks; + kgid_t *blocks[0]; +}; + +extern struct user_namespace init_user_ns; +#define current_user_ns() (&init_user_ns) + +struct group_info *get_current_groups(); + +/************************* + ** asm-generic/fcntl.h ** + *************************/ + +enum { O_NONBLOCK = 0x4000 }; + + +/********************* + ** uapi/linux/fs.h ** + *********************/ + +enum { + NR_FILE = 8192, +}; + + +/**************** + ** linux/fs.h ** + ****************/ + +struct fown_struct { }; + +struct file +{ + unsigned int f_flags; + const struct cred *f_cred; + struct fown_struct f_owner; +}; + +typedef struct +{ + size_t count; + union + { + void *data; + } arg; +} read_descriptor_t; + +struct inode +{ + umode_t i_mode; + kuid_t i_uid; + unsigned long i_ino; +}; + +struct inode *file_inode(struct file *f); + + +/*********************** + ** linux/pipe_fs_i.h ** + ***********************/ + +struct pipe_buffer +{ + struct page *page; +}; + +struct pipe_inode_info; + +struct pipe_buf_operations +{ + int can_merge; + void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int); + void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *); + int (*confirm)(struct pipe_inode_info *, struct pipe_buffer *); + void (*release)(struct pipe_inode_info *, struct pipe_buffer *); + int (*steal)(struct pipe_inode_info *, struct pipe_buffer *); + void (*get)(struct pipe_inode_info *, struct pipe_buffer *); +}; + +void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int); +void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *); +int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *); + + +/******************** + ** linux/splice.h ** + ********************/ + +struct partial_page +{ + unsigned int offset; + unsigned int len; +}; + +struct splice_pipe_desc +{ + struct page **pages; + struct partial_page *partial; + int nr_pages; + unsigned int nr_pages_max; + unsigned int flags; + + const struct pipe_buf_operations *ops; + void (*spd_release)(struct splice_pipe_desc *, unsigned int); +}; + + +/***************** + ** linux/aio.h ** + *****************/ +#ifdef __cplusplus +#define private priv +#endif +struct kiocb +{ + void *private; +}; + +#ifdef __cplusplus +#undef private +#endif + +/***************** + ** linux/uio.h ** + *****************/ + +enum { UIO_MAXIOV = 1024 }; + +struct iovec +{ + void *iov_base; + __kernel_size_t iov_len; +}; + +struct kvec +{ + void *iov_base; + size_t iov_len; +}; + +int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); + + +/******************************* + ** uapi/asm-generic/ioctls.h ** + *******************************/ + +enum { + TIOCOUTQ = 0x5411, + FIONREAD = 0x541b, +}; + + +/********************* + ** linux/utsname.h ** + *********************/ + +enum { __NEW_UTS_LEN = 64 }; + +struct new_utsname +{ + char nodename[65]; + char domainname[65]; +}; + +struct uts_name { + struct new_utsname name; +}; + +extern struct uts_name init_uts_ns; + +struct new_utsname *init_utsname(void); +struct new_utsname *utsname(void); + + +/************************* + ** uapi/linux/filter.h ** + *************************/ + +struct sock_fprog { }; + +/******************** + ** linux/filter.h ** + ********************/ + +struct sk_filter +{ + atomic_t refcnt; + struct rcu_head rcu; +}; + + +/***************************** + ** uapi/linux/hdlc/ioctl.h ** + *****************************/ + +typedef struct { } fr_proto; +typedef struct { } fr_proto_pvc; +typedef struct { } fr_proto_pvc_info; +typedef struct { } cisco_proto; +typedef struct { } raw_hdlc_proto; +typedef struct { } te1_settings; +typedef struct { } sync_serial_settings; + + +/*********************** + ** linux/workquque.h ** + ***********************/ + +struct workqueue_struct { }; + +struct work_struct; +typedef void (*work_func_t)(struct work_struct *work); + +struct work_struct { + work_func_t func; + struct list_head entry; +}; + +struct delayed_work +{ + struct work_struct work; +}; + +#define DECLARE_DELAYED_WORK(n, f) \ + struct delayed_work n + +#define __WORK_INITIALIZER(n, f) { \ + .entry = { &(n).entry, &(n).entry }, \ + .func = (f) \ +} + +extern struct workqueue_struct *system_wq; + + +/********************** + ** linux/inerrupt.h ** + **********************/ + +struct tasklet_struct +{ }; + + +/******************** + ** linux/crypto.h ** + ********************/ + +struct hash_desc { }; + +/************************ + ** linux/cryptohash.h ** + ************************/ + +enum { + SHA_DIGEST_WORDS = 5, + SHA_MESSAGE_BYTES = 512 * 8, + SHA_WORKSPACE_WORDS = 16, +}; + + +/********************** + ** linx/rtnetlink.h ** + **********************/ + +struct net_device; + +struct netdev_queue *dev_ingress_queue(struct net_device *dev); + + +/******************** + ** net/netevent.h ** + ********************/ + +enum netevent_notif_type { + NETEVENT_NEIGH_UPDATE = 1, /* arg is struct neighbour ptr */ +}; + + +/*************** + ** net/scm.h ** + ***************/ + +struct scm_creds +{ +}; + +struct scm_cookie +{ + struct scm_creds creds; +}; + + +/********************* + ** net/fib_rules.h ** + *********************/ + +enum { FIB_LOOKUP_NOREF = 1 }; + + +/**************************** + ** linux/u64_stats_sync.h ** + ****************************/ + +struct u64_stats_sync { }; + + +/************************* + ** net/net_namespace.h ** + *************************/ + +#define new _new +#include +#undef new +#include +#include +#include + +enum { + LOOPBACK_IFINDEX = 1, + NETDEV_HASHBITS = 8, + NETDEV_HASHENTRIES = 1 << NETDEV_HASHBITS, +}; + +struct user_namespace; + +extern struct net init_net; + +struct net +{ + struct list_head list; + struct list_head exit_list; + struct list_head dev_base_head; + struct hlist_head *dev_name_head; + struct hlist_head *dev_index_head; + unsigned int dev_base_seq; + int ifindex; + struct net_device *loopback_dev; + struct user_namespace *user_ns; + struct proc_dir_entry *proc_net_stat; + struct sock *rtnl; + struct netns_mib mib; + struct netns_ipv4 ipv4; + atomic_t rt_genid; + +}; + + +struct pernet_operations +{ + int (*init)(struct net *net); + void (*exit)(struct net *net); + void (*exit_batch)(struct list_head *net_exit_list); +}; + +extern struct list_head net_namespace_list; + +#define __net_initdata +#define __net_init +#define __net_exit + +#define for_each_net(VAR) \ + for(VAR = &init_net; VAR; VAR = 0) + +#define read_pnet(pnet) (&init_net) +#define write_pnet(pnet, net) do { (void)(net);} while (0) + +static inline struct net *hold_net(struct net *net) { return net; } +static inline struct net *get_net(struct net *net) { return net; } +static inline void put_net(struct net *net) { } +static inline int net_eq(const struct net *net1, const struct net *net2) { + return net1 == net2; } + +struct net *get_net_ns_by_pid(pid_t pid); +struct net *get_net_ns_by_fd(int pid); + +int register_pernet_subsys(struct pernet_operations *); +int register_pernet_device(struct pernet_operations *); + +/************************** + ** linux/seq_file_net.h ** + **************************/ + +struct seq_net_private { + struct net *net; +}; + +struct seq_operations { }; + + +/************************** + ** linux/seq_file.h ** + **************************/ + +struct seq_file { }; + + +/************************** + ** linux/seqlock.h ** + **************************/ + +typedef struct seqcount { + unsigned sequence; +} seqcount_t; + +unsigned read_seqbegin(const seqlock_t *sl); +unsigned read_seqretry(const seqlock_t *sl, unsigned start); + +/********************** + ** linux/notifier.h ** + **********************/ + +enum { + NOTIFY_DONE = 0, + NOTIFY_OK = 0x1, + NOTIFY_STOP_MASK = 0x8000, + + NETLINK_URELEASE = 0x1, +}; + + +struct notifier_block; + +typedef int (*notifier_fn_t)(struct notifier_block *nb, + unsigned long action, void *data); + +struct notifier_block +{ + notifier_fn_t notifier_call; + struct notifier_block *next; + int priority; +}; + +struct raw_notifier_head +{ + struct notifier_block *head; +}; + +#define RAW_NOTIFIER_HEAD(name) \ + struct raw_notifier_head name; + +struct blocking_notifier_head { + struct rw_semaphore rwsem; + struct notifier_block *head; +}; + +struct atomic_notifier_head { + struct notifier_block *head; + +}; + +int raw_notifier_chain_register(struct raw_notifier_head *nh, + struct notifier_block *n); + +int raw_notifier_call_chain(struct raw_notifier_head *nh, + unsigned long val, void *v); + +int blocking_notifier_chain_register(struct blocking_notifier_head *nh, + struct notifier_block *n); + +int blocking_notifier_call_chain(struct blocking_notifier_head *nh, + unsigned long val, void *v); + +#define BLOCKING_NOTIFIER_INIT(name) { \ + .rwsem = __RWSEM_INITIALIZER((name).rwsem), .head = NULL } + +#define BLOCKING_NOTIFIER_HEAD(name) \ + struct blocking_notifier_head name = BLOCKING_NOTIFIER_INIT(name) + +#define ATOMIC_NOTIFIER_INIT(name) { \ + .head = NULL } + +#define ATOMIC_NOTIFIER_HEAD(name) \ + struct atomic_notifier_head name = ATOMIC_NOTIFIER_INIT(name) + + +/**************************** + ** asm-generic/checksum.h ** + ****************************/ + +__sum16 csum_fold(__wsum csum); +__sum16 ip_fast_csum(const void *iph, unsigned int ihl); + +__wsum csum_partial(const void *buff, int len, __wsum sum); +__wsum csum_partial_copy(const void *src, void *dst, int len, __wsum sum); +__wsum csum_partial_copy_from_user(const void __user *src, void *dst, int len, + __wsum sum, int *csum_err); + +#define csum_partial_copy_nocheck(src, dst, len, sum) \ + csum_partial_copy((src), (dst), (len), (sum)) + +#define csum_and_copy_from_user csum_partial_copy_from_user + +__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum); + +static inline +__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); +} + +static inline +__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len, + __wsum sum, int *err_ptr) +{ + sum = csum_partial(src, len, sum); + + memcpy(dst, src, len); + return sum; +} + + +/********************* + ** linux/if_vlan.h ** + *********************/ + +enum { VLAN_HLEN = 4 }; + +struct vlan_hdr +{ + __be16 h_vlan_encapsulated_proto; +}; + +struct vlan_ethhdr +{ + __be16 h_vlan_encapsulated_proto; +}; + +static inline +struct net_device *vlan_dev_real_dev(const struct net_device *dev) +{ + return NULL; +} + +#define vlan_tx_tag_get(__skb) 0 +struct sk_buff *__vlan_put_tag(struct sk_buff *skb, u16 vlan_tci); +struct sk_buff *vlan_untag(struct sk_buff *skb); + + +/******************** + ** net/checksum.h ** + ********************/ + +#define CSUM_MANGLED_0 ((__sum16)0xffff) + +__wsum csum_and_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *err_ptr); +__wsum csum_add(__wsum csum, __wsum addend); +__wsum csum_block_add(__wsum csum, __wsum csum2, int offset); +__wsum csum_sub(__wsum csum, __wsum addend); + +/***************************** + ** uapi/linux/net_tstamp.h ** + *****************************/ + +#ifdef __cplusplus +#define class device_class +#endif +#include +#ifdef __cplusplus +#undef class +#endif +#include + +enum { + SOF_TIMESTAMPING_TX_HARDWARE = 1 << 0, + SOF_TIMESTAMPING_TX_SOFTWARE = 1 << 1, + SOF_TIMESTAMPING_RX_HARDWARE = 1 << 2, + SOF_TIMESTAMPING_RX_SOFTWARE = 1 << 3, + SOF_TIMESTAMPING_SOFTWARE = 1 << 4, + SOF_TIMESTAMPING_SYS_HARDWARE = 1 << 5, + SOF_TIMESTAMPING_RAW_HARDWARE = 1 << 6, + SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_RAW_HARDWARE - 1) | + SOF_TIMESTAMPING_RAW_HARDWARE, +}; + + +struct rtnl_link_ops +{ + struct list_head list; + const char *kind; + size_t priv_size; + void (*setup)(struct net_device *dev); + int maxtype; + const struct nla_policy *policy; + void (*dellink)(struct net_device *dev, + struct list_head *head); + size_t (*get_size)(const struct net_device *dev); + size_t (*get_xstats_size)(const struct net_device *dev); + + int (*fill_info)(struct sk_buff *skb, + const struct net_device *dev); + int (*fill_xstats)(struct sk_buff *skb, + const struct net_device *dev); + unsigned int (*get_num_tx_queues)(void); + unsigned int (*get_num_rx_queues)(void); + int (*changelink)(struct net_device *dev, + struct nlattr *tb[], + struct nlattr *data[]); + int (*validate)(struct nlattr *tb[], + struct nlattr *data[]); + int (*newlink)(struct net *src_net, + struct net_device *dev, + struct nlattr *tb[], + struct nlattr *data[]); +}; + +struct rtnl_af_ops +{ + struct list_head list; + int family; + + size_t (*get_link_af_size)(const struct net_device *dev); + int (*fill_link_af)(struct sk_buff *skb, + const struct net_device *dev); + int (*validate_link_af)(const struct net_device *dev, + const struct nlattr *attr); + int (*set_link_af)(struct net_device *dev, + const struct nlattr *attr); +}; + +typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *, void *); +typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *); +typedef u16 (*rtnl_calcit_func)(struct sk_buff *, struct nlmsghdr *); + +#define rtnl_dereference(p) p + +extern const struct nla_policy ifla_policy[IFLA_MAX+1]; + +void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change); + + +/********************** + ** net/gent_stats.h ** + **********************/ + +struct gnet_dump { }; + +/*************** + ** net/tcp.h ** + ***************/ + +enum { + TFO_SERVER_ENABLE = 2, + TFO_SERVER_WO_SOCKOPT1 = 0x400, + TFO_SERVER_WO_SOCKOPT2 = 0x800, +}; + +extern int sysctl_tcp_fastopen; + + +/******************************** + ** uapi/asm-generic/sockios.h ** + ********************************/ + +enum { + SIOCATMARK = 0x8905, + SIOCGSTAMP = 0x8906, + SIOCGSTAMPNS = 0x8907, +}; + + +/**************** + ** linux/ip.h ** + ****************/ + +struct ip_hdr; + +struct iphdr *ip_hdr(const struct sk_buff *skb); + + +/******************************** + ** uapi/linux/netfilter_arp.h ** + ********************************/ + +enum { + NF_ARP_IN = 0, + NF_ARP_OUT = 1, +}; + + +/**************** + ** net/ax25.h ** + ****************/ + +enum { AX25_P_IP = 0xcc }; + + +/******************** + ** net/addrconf.h ** + ********************/ + +enum { + ADDR_CHECK_FREQUENCY = (120*HZ), + ADDRCONF_TIMER_FUZZ_MINUS = (HZ > 50 ? HZ / 50 : 1), + ADDRCONF_TIMER_FUZZ = (HZ / 4), + ADDRCONF_TIMER_FUZZ_MAX = (HZ), +}; + + +/*********************** + ** uapi/linux/xfrm.h ** + ***********************/ + +enum { + XFRM_POLICY_IN = 0, + XFRM_POLICY_FWD = 2, + + XFRM_MAX_DEPTH = 6, + XFRM_STATE_ICMP = 16, +}; + + +/**************** + ** net/xfrm.h ** + ****************/ + +struct xfrm_state +{ + struct + { + u8 flags; + } props; +}; + +struct sec_path +{ + int len; + struct xfrm_state *xvec[XFRM_MAX_DEPTH]; +}; + + +/********************* + ** net/incet_ecn.h ** + *********************/ + +enum { + INET_ECN_CE = 3, + INET_ECN_MASK = 3, +}; + + +/****************** + ** linux/igmp.h ** + ******************/ + +extern int sysctl_igmp_max_msf; + + +/************************** + ** uapi/linux/pkg_sched ** + **************************/ + +#include + +enum { + TC_PRIO_BESTEFFORT = 0, + TC_PRIO_BULK = 2, + TC_PRIO_INTERACTIVE_BULK = 4, + TC_PRIO_INTERACTIVE = 6, +}; + + +/*********************** + ** linux/inet_diag.h ** + ***********************/ + + +struct inet_diag_handler +{ + void (*dump)(struct sk_buff *skb, + struct netlink_callback *cb, + struct inet_diag_req_v2 *r, + struct nlattr *bc); + + int (*dump_one)(struct sk_buff *in_skb, + const struct nlmsghdr *nlh, + struct inet_diag_req_v2 *req); + + void (*idiag_get_info)(struct sock *sk, + struct inet_diag_msg *r, + void *info); + __u16 idiag_type; +}; + + +/******************** + ** net/inet_ecn.h ** + ********************/ + +enum { + INET_ECN_NOT_ECT = 0, +}; + + + +/***************** + ** net/xfrm4.h ** + *****************/ + +int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb); + + +/********************* + ** linux/netpoll.h ** + *********************/ + +struct napi_struct; + +void *netpoll_poll_lock(struct napi_struct *napi); + + +/************************ + ** net/ethernet/eth.c ** + ************************/ + +extern const struct header_ops eth_header_ops; + + +/*********************** + ** linux/netfilter.h ** + ***********************/ + +#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) +#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb) + + +/**************** + ** linux/in.h ** + ****************/ + +#define INADDR_BROADCAST ((unsigned long int) 0xffffffff) + +static inline bool ipv4_is_multicast(__be32 addr) +{ + return (addr & htonl(0xf0000000)) == htonl(0xe0000000); +} + +static inline bool ipv4_is_zeronet(__be32 addr) +{ + return (addr & htonl(0xff000000)) == htonl(0x00000000); +} + +static inline bool ipv4_is_lbcast(__be32 addr) +{ + /* limited broadcast */ + return addr == htonl(INADDR_BROADCAST); +} + +static inline bool ipv4_is_loopback(__be32 addr) +{ + return (addr & htonl(0xff000000)) == htonl(0x7f000000); +} + +#define IP_FMT "%u.%u.%u.%u" +#define IP_ARG(x) (x >> 0) & 0xff, (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ARG(x) x[0], x[1], x[2], x[3], x[4], x[5] + +#include + + +/** + * Misc + */ + +void set_sock_wait(struct socket *sock, unsigned long ptr); +int socket_check_state(struct socket *sock); +void log_sock(struct socket *sock); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _LX_EMUL_H_ */ + diff --git a/dde_linux/src/lib/lxip/include/net/fib_rules.h b/dde_linux/src/lib/lxip/include/net/fib_rules.h new file mode 100644 index 000000000..8d5766518 --- /dev/null +++ b/dde_linux/src/lib/lxip/include/net/fib_rules.h @@ -0,0 +1 @@ +#include diff --git a/dde_linux/src/lib/lxip/include/net/gen_stats.h b/dde_linux/src/lib/lxip/include/net/gen_stats.h new file mode 100644 index 000000000..be44e8e9b --- /dev/null +++ b/dde_linux/src/lib/lxip/include/net/gen_stats.h @@ -0,0 +1 @@ +#include diff --git a/dde_linux/src/lib/lxip/include/net/inet_ecn.h b/dde_linux/src/lib/lxip/include/net/inet_ecn.h new file mode 100644 index 000000000..3f3cc1850 --- /dev/null +++ b/dde_linux/src/lib/lxip/include/net/inet_ecn.h @@ -0,0 +1 @@ +#include diff --git a/dde_linux/src/lib/lxip/include/net/xfrm.h b/dde_linux/src/lib/lxip/include/net/xfrm.h new file mode 100644 index 000000000..cb4d69913 --- /dev/null +++ b/dde_linux/src/lib/lxip/include/net/xfrm.h @@ -0,0 +1,6 @@ +#include +#include + +struct ipv6hdr; + +#include diff --git a/dde_linux/src/lib/lxip/include/nic.h b/dde_linux/src/lib/lxip/include/nic.h new file mode 100644 index 000000000..0686b6317 --- /dev/null +++ b/dde_linux/src/lib/lxip/include/nic.h @@ -0,0 +1,27 @@ +/** + * \brief C back-end + * \author Sebastian Sumpf + * \date 2013-09-09 + */ + +/* + * 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. + */ +#ifndef _INCLUDE__NIC_H_ +#define _INCLUDE__NIC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void net_mac(void* mac, unsigned long size); +int net_tx(void* addr, unsigned long len); +void net_driver_rx(void *addr, unsigned long size); + +#ifdef __cplusplus +} +#endif +#endif /* _INCLUDE__NIC_H_ */ diff --git a/dde_linux/src/lib/lxip/include/packet_handler.h b/dde_linux/src/lib/lxip/include/packet_handler.h new file mode 100644 index 000000000..77273c4cf --- /dev/null +++ b/dde_linux/src/lib/lxip/include/packet_handler.h @@ -0,0 +1,73 @@ +/* + * \brief Signal driven network handler + * \author Stefan Kalkowski + * \auhtor Sebastian Sumpf + * \date 2013-09-24 + */ + +/* + * 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. + */ + +#ifndef _PACKET_HANDLER_H_ +#define _PACKET_HANDLER_H_ + +/* Genode */ +#include + +namespace Net { + class Packet_handler; +} + + +/** + * Generic packet handler used as base for NIC and client packet handlers. + */ +class Net::Packet_handler +{ + private: + + /** + * submit queue not empty anymore + */ + void _packet_avail(unsigned); + + /** + * acknoledgement queue not full anymore + */ + void _ready_to_ack(unsigned); + + /** + * acknoledgement queue not empty anymore + */ + void _ack_avail(unsigned); + + /** + * submit queue not full anymore + * + * TODO: by now, we just drop packets that cannot be transferred + * to the other side, that's why we ignore this signal. + */ + void _ready_to_submit(unsigned) { } + + protected: + + Genode::Signal_dispatcher _sink_ack; + Genode::Signal_dispatcher _sink_submit; + Genode::Signal_dispatcher _source_ack; + Genode::Signal_dispatcher _source_submit; + + public: + + Packet_handler(); + + virtual Packet_stream_sink< ::Nic::Session::Policy> * sink() = 0; + virtual Packet_stream_source< ::Nic::Session::Policy> * source() = 0; + + void packet_avail() { _packet_avail(1); } +}; + +#endif /* _PACKET_HANDLER_H_ */ diff --git a/dde_linux/src/lib/lxip/init.c b/dde_linux/src/lib/lxip/init.c new file mode 100644 index 000000000..465ac1082 --- /dev/null +++ b/dde_linux/src/lib/lxip/init.c @@ -0,0 +1,78 @@ +/** + * \brief IP stack initialization + * \author Sebastian Sumpf + * \date 2013-08-26 + */ + +/* + * 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 +#include +#include +#include +/* + * Header declarations and tuning + */ +struct net init_net; + +unsigned long *sysctl_local_reserved_ports; +struct pernet_operations loopback_net_ops; + + +/** + * nr_free_buffer_pages - count number of pages beyond high watermark + * + * nr_free_buffer_pages() counts the number of pages which are beyond the + * high + * watermark within ZONE_DMA and ZONE_NORMAL. + */ +unsigned long nr_free_buffer_pages(void) +{ + return 1000; +} + + +/** + * Initialize sub-systems + */ +int lxip_init() +{ + /* init data */ + INIT_LIST_HEAD(&init_net.dev_base_head); + + + /*start jiffies */ + dde_kit_timer_init(0, 0); + + /* call __setup stuff */ + __ip_auto_config_setup("dhcp"); + + core_sock_init(); + core_netlink_proto_init(); + + /* sub-systems */ + subsys_net_dev_init(); + fs_inet_init(); + + /* enable local accepts */ + IPV4_DEVCONF_ALL(&init_net, ACCEPT_LOCAL) = 0x1; + + /* congestion control */ + module_cubictcp_register(); + + /* driver */ + module_driver_init(); + + /* late */ + late_tcp_congestion_default(); + + /* dhcp */ + late_ip_auto_config(); + + return 1; +} + diff --git a/dde_linux/src/lib/lxip/lxc_emul.c b/dde_linux/src/lib/lxip/lxc_emul.c new file mode 100644 index 000000000..ad62c313b --- /dev/null +++ b/dde_linux/src/lib/lxip/lxc_emul.c @@ -0,0 +1,393 @@ +/** + * \brief Linux emulation code + * \author Sebastian Sumpf + * \date 2013-08-30 + */ + +/* + * 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 +#include +#include +#include +#include +#include + + +/******************** + ** linux/slab.h ** + ********************/ + +struct kmem_cache +{ + const char *name; /* cache name */ + unsigned size; /* object size */ +}; + + +struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align, + unsigned long falgs, void (*ctor)(void *)) +{ + dde_kit_log(DEBUG_SLAB, "\"%s\" obj_size=%zd", name, size); + + struct kmem_cache *cache; + + if (!name) { + pr_info("kmem_cache name required\n"); + return 0; + } + + cache = (struct kmem_cache *)kmalloc(sizeof(*cache), 0); + if (!cache) { + pr_crit("No memory for slab cache\n"); + return 0; + } + + cache->name = name; + cache->size = size; + + return cache; +} + + +void *kmem_cache_alloc_node(struct kmem_cache *cache, gfp_t flags, int node) +{ + dde_kit_log(DEBUG_SLAB, "\"%s\" alloc obj_size=%zd", cache->name,cache->size); + return kmalloc(cache->size, 0); +} + + +void *kmem_cache_alloc(struct kmem_cache *cache, gfp_t flags) +{ + dde_kit_log(DEBUG_SLAB, "\"%s\" alloc obj_size=%zd", cache->name,cache->size); + return kmalloc(cache->size, 0); +} + + +void kmem_cache_free(struct kmem_cache *cache, void *objp) +{ + dde_kit_log(DEBUG_SLAB, "\"%s\" (%p)", cache->name, objp); + kfree(objp); +} + + +void *alloc_large_system_hash(const char *tablename, + unsigned long bucketsize, + unsigned long numentries, + int scale, + int flags, + unsigned int *_hash_shift, + unsigned int *_hash_mask, + unsigned long low_limit, + unsigned long high_limit) +{ + unsigned long elements = numentries ? numentries : high_limit; + unsigned long nlog2 = ilog2(elements); + nlog2 <<= (1 << nlog2) < elements ? 1 : 0; + + void *table = dde_kit_simple_malloc(elements * bucketsize); + + if (_hash_mask) + *_hash_mask = (1 << nlog2) - 1; + if (_hash_shift) + *_hash_shift = nlog2; + + return table; +} + +/******************** + ** linux/bitmap.h ** + ********************/ + +void bitmap_fill(unsigned long *dst, int nbits) +{ + int count = nbits / (8 * sizeof (long)); + int i; + + memset(dst, 0xff, count * sizeof(long)); + dst += count; + + count = nbits % (8 * sizeof(long)); + + for (i = 0; i < count; i++) + *dst |= (1 << i); +} + + +void bitmap_zero(unsigned long *dst, int nbits) +{ + int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); + memset(dst, 0, len); +} + + +/***************** + ** linux/gfp.h ** + *****************/ + +unsigned long get_zeroed_page(gfp_t gfp_mask) +{ + return (unsigned long)kzalloc(PAGE_SIZE, 0); +} + + +/******************** + ** linux/percpu.h ** + ********************/ + +void *__alloc_percpu(size_t size, size_t align) +{ + return kmalloc(size, 0); +} + + +/****************** + ** linux/hash.h ** + ******************/ + +u32 hash_32(u32 val, unsigned int bits) +{ + enum { GOLDEN_RATIO_PRIME_32 = 0x9e370001UL }; + u32 hash = val * GOLDEN_RATIO_PRIME_32; + + hash = hash >> (32 - bits); + return hash; +} + +/****************** + ** linux/dcache ** + ******************/ + +unsigned int full_name_hash(const unsigned char *name, unsigned int len) +{ + unsigned hash = 0, i; + for (i = 0; i < len; i++) + hash += name[i]; + + return hash; +} + +/****************************** + * net/core/net/namespace.h ** + ******************************/ + +int register_pernet_subsys(struct pernet_operations *ops) +{ + if (ops->init) + ops->init(&init_net); + + return 0; +} + +int register_pernet_device(struct pernet_operations *ops) +{ + return register_pernet_subsys(ops); +} + + +/************************* + ** net/net_namespace.h ** + *************************/ + +int rt_genid(struct net *net) +{ + int ret = atomic_read(&net->rt_genid); + return -1; +} + + +/********************** + ** linx/rtnetlink.h ** + **********************/ + +struct netdev_queue *dev_ingress_queue(struct net_device *dev) +{ + return dev->ingress_queue; +} + + +/**************** + ** linux/ip.h ** + ****************/ + +struct iphdr *ip_hdr(const struct sk_buff *skb) +{ + return (struct iphdr *)skb_network_header(skb); +} + + +/*********************** + ** linux/netdevice.h ** + ***********************/ + + struct netdev_queue *netdev_pick_tx(struct net_device *dev, struct sk_buff *skb) + { + return netdev_get_tx_queue(dev, 0); + } + + +/******************************* + ** asm-generic/bitops/find.h ** + *******************************/ + +unsigned long find_first_zero_bit(unsigned long const *addr, unsigned long size) +{ + unsigned long i, j; + + for (i = 0; i < (size / BITS_PER_LONG); i++) + if (addr[i] != ~0UL) + break; + + if (i == size) + return size; + + for (j = 0; j < BITS_PER_LONG; j++) + if ((~addr[i]) & (1 << j)) + break; + + return (i * BITS_PER_LONG) + j; +} + + +/**************************** + ** asm-generic/getorder.h ** + ****************************/ + +int get_order(unsigned long size) +{ + int order; + + size--; + size >>= PAGE_SHIFT; + + order = __builtin_ctzl(size); + return order; +} + + +/********************* + ** linux/jiffies.h ** + *********************/ + +long time_after_eq(long a, long b) { return (a - b) >= 0; } +long time_after(long a, long b) { return (b - a) < 0; } + + +/********************* + ** linux/utsname.h ** + *********************/ + +struct uts_name init_uts_ns; + +struct new_utsname *init_utsname(void) { return &init_uts_ns.name; } +struct new_utsname *utsname(void) { return init_utsname(); } + + +/********************** + ** linux/notifier.h ** + **********************/ + +int raw_notifier_chain_register(struct raw_notifier_head *nh, + struct notifier_block *n) +{ + struct notifier_block *nl = nh->head; + struct notifier_block *pr = 0; + while (nl) { + if (n->priority > nl->priority) + break; + pr = nl; + nl = nl->next; + } + + n->next = nl; + if (pr) + pr->next = n; + else + nh->head = n; + + return 0; +} + + +int raw_notifier_call_chain(struct raw_notifier_head *nh, + unsigned long val, void *v) +{ + int ret = NOTIFY_DONE; + struct notifier_block *nb = nh->head; + + while (nb) { + + ret = nb->notifier_call(nb, val, v); + if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK) + break; + + nb = nb->next; + } + + return ret; +} + + +int blocking_notifier_chain_register(struct blocking_notifier_head *nh, + struct notifier_block *n) +{ + return raw_notifier_chain_register((struct raw_notifier_head *)nh, n); +} + + +int blocking_notifier_call_chain(struct blocking_notifier_head *nh, + unsigned long val, void *v) +{ + return raw_notifier_call_chain((struct raw_notifier_head *)nh, val, v); +} + + +/**************************** + ** asm-generic/checksum.h ** + ****************************/ + +__sum16 csum_fold(__wsum csum) +{ + u32 sum = (u32)csum; + sum = (sum & 0xffff) + (sum >> 16); + sum = (sum & 0xffff) + (sum >> 16); + return (__sum16)~sum; +} + + +/******************* +** net/checksum.h ** +********************/ + +__wsum csum_add(__wsum csum, __wsum addend) +{ + u32 res = (u32)csum; + res += (u32)addend; + return (__wsum)(res + (res < (u32)addend)); +} + + +__wsum csum_block_add(__wsum csum, __wsum csum2, int offset) +{ + u32 sum = (u32)csum2; + if (offset&1) + sum = ((sum&0xFF00FF)<<8)+((sum>>8)&0xFF00FF); + return csum_add(csum, (__wsum)sum); +} + + +/** + * Misc + */ + +void set_sock_wait(struct socket *sock, unsigned long ptr) +{ + + sock->sk->sk_wq = (struct socket_wq *)ptr; +} + + diff --git a/dde_linux/src/lib/lxip/lxcc_emul.cc b/dde_linux/src/lib/lxip/lxcc_emul.cc new file mode 100644 index 000000000..60917e425 --- /dev/null +++ b/dde_linux/src/lib/lxip/lxcc_emul.cc @@ -0,0 +1,635 @@ +/** + * \brief Linux emulation code + * \author Sebastian Sumpf + * \date 2013-08-28 + */ + +/* + * 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 +#include +#include +#include + +#include +#include + +extern "C" { +#include +} + +/* + * VM-area to reserve for back-end allocator + */ +enum { VM_RESERVATION = 24 * 1024 * 1024 }; + +/* + * TODO: fine tune these + */ +unsigned long totalram_pages = VM_RESERVATION / PAGE_SIZE; +unsigned long num_physpages = totalram_pages; + +namespace Genode { + template class Slab_backend_alloc; + typedef Slab_backend_alloc Backend_alloc; + class Slab_alloc; +} + +/** + * Back-end allocator for Genode's slab allocator + */ +template +class Genode::Slab_backend_alloc : public Genode::Allocator, + public Genode::Rm_connection +{ + private: + + enum { + BLOCK_SIZE = 1024 * 1024, /* 1 MB */ + ELEMENTS = VM_SIZE / BLOCK_SIZE, /* MAX number of dataspaces in VM */ + }; + + addr_t _base; /* virt. base address */ + bool _cached; /* non-/cached RAM */ + Ram_dataspace_capability _ds_cap[ELEMENTS]; /* dataspaces to put in VM */ + addr_t _ds_phys[ELEMENTS]; /* physical bases of dataspaces */ + int _index; /* current index in ds_cap */ + Allocator_avl _range; /* manage allocations */ + + bool _alloc_block() + { + if (_index == ELEMENTS) { + PERR("Slab-backend exhausted!"); + return false; + } + + try { + _ds_cap[_index] = Genode::env()->ram_session()->alloc(BLOCK_SIZE, _cached); + /* attach at index * BLOCK_SIZE */ + Rm_connection::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0); + + /* lookup phys. address */ + _ds_phys[_index] = Dataspace_client(_ds_cap[_index]).phys_addr(); + } catch (...) { return false; } + + /* return base + offset in VM area */ + addr_t block_base = _base + (_index * BLOCK_SIZE); + ++_index; + + _range.add_range(block_base, BLOCK_SIZE); + return true; + } + + public: + + Slab_backend_alloc(bool cached) + : Rm_connection(0, VM_SIZE), _cached(cached), _index(0), + _range(env()->heap()) + { + /* reserver attach us, anywere */ + _base = env()->rm_session()->attach(dataspace()); + } + + /** + * Allocate + */ + bool alloc(size_t size, void **out_addr) + { + bool done = _range.alloc(size, out_addr); + + if (done) + return done; + + done = _alloc_block(); + if (!done) { + PERR("Backend allocator exhausted\n"); + return false; + } + + return _range.alloc(size, out_addr); + } + + void free(void *addr, size_t /* size */) { } + size_t overhead(size_t size) { return 0; } + + /** + * Return phys address for given virtual addr. + */ + addr_t phys_addr(addr_t addr) + { + if (addr < _base || addr >= (_base + VM_SIZE)) + return ~0UL; + + int index = (addr - _base) / BLOCK_SIZE; + + /* physical base of dataspace */ + addr_t phys = _ds_phys[index]; + + if (!phys) + return ~0UL; + + /* add offset */ + phys += (addr - _base - (index * BLOCK_SIZE)); + return phys; + } + + addr_t start() const { return _base; } + addr_t end() const { return _base + VM_SIZE - 1; } +}; + + +/** + * Slab allocator using our back-end allocator + */ +class Genode::Slab_alloc : public Genode::Slab +{ + private: + + size_t _calculate_block_size(size_t object_size) + { + size_t block_size = 8 * (object_size + sizeof(Slab_entry)) + sizeof(Slab_block); + return align_addr(block_size, 12); + } + + public: + + Slab_alloc(size_t object_size, Backend_alloc *allocator) + : Slab(object_size, _calculate_block_size(object_size), 0, allocator) + { } + + inline addr_t alloc() + { + addr_t result; + return (Slab::alloc(slab_size(), (void **)&result) ? result : 0); + } +}; + +/** + * Memory interface used used for Linux emulation + */ +class Malloc +{ + private: + + enum { + SLAB_START_LOG2 = 3, /* 8 B */ + SLAB_STOP_LOG2 = 16, /* 64 KB */ + NUM_SLABS = (SLAB_STOP_LOG2 - SLAB_START_LOG2) + 1, + }; + + typedef Genode::addr_t addr_t; + typedef Genode::Slab_alloc Slab_alloc; + typedef Genode::Slab_backend_alloc Slab_backend_alloc; + + Slab_backend_alloc *_back_allocator; + Slab_alloc *_allocator[NUM_SLABS]; + bool _cached; /* cached or un-cached memory */ + addr_t _start; /* VM region of this allocator */ + addr_t _end; + + /** + * Set 'value' at 'addr' + */ + void _set_at(addr_t addr, addr_t value) { *((addr_t *)addr) = value; } + + /** + * Retrieve slab index belonging to given address + */ + unsigned _slab_index(Genode::addr_t **addr) + { + using namespace Genode; + /* get index */ + addr_t index = *(*addr - 1); + + /* + * If index large, we use aligned memory, retrieve beginning of slab entry + * and read index from there + */ + if (index > 32) { + *addr = (addr_t *)*(*addr - 1); + index = *(*addr - 1); + } + + return index; + } + + public: + + Malloc(Slab_backend_alloc *alloc, bool cached) + : _back_allocator(alloc), _cached(cached), _start(alloc->start()), + _end(alloc->end()) + { + /* init slab allocators */ + for (unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++) + _allocator[i - SLAB_START_LOG2] = new (Genode::env()->heap()) + Slab_alloc(1U << i, alloc); + } + + /** + * Alloc in slabs + */ + void *alloc(Genode::size_t size, int align = 0, Genode::addr_t *phys = 0) + { + using namespace Genode; + /* += slab index + aligment size */ + size += sizeof(addr_t) + (align > 2 ? (1 << align) : 0); + + int msb = Genode::log2(size); + + if (size > (1U << msb)) + msb++; + + if (size < (1U << SLAB_START_LOG2)) + msb = SLAB_STOP_LOG2; + + if (msb > SLAB_STOP_LOG2) { + PERR("Slab too large %u requested %zu cached %d", 1U << msb, size, _cached); + return 0; + } + + addr_t addr = _allocator[msb - SLAB_START_LOG2]->alloc(); + if (!addr) { + PERR("Failed to get slab for %u", 1 << msb); + return 0; + } + + _set_at(addr, msb - SLAB_START_LOG2); + addr += sizeof(addr_t); + + if (align > 2) { + /* save */ + addr_t ptr = addr; + addr_t align_val = (1U << align); + addr_t align_mask = align_val - 1; + /* align */ + addr = (addr + align_val) & ~align_mask; + /* write start address before aligned address */ + _set_at(addr - sizeof(addr_t), ptr); + } + + if (phys) + *phys = _back_allocator->phys_addr(addr); + return (addr_t *)addr; + } + + void free(void const *a) + { + using namespace Genode; + addr_t *addr = (addr_t *)a; + + unsigned nr = _slab_index(&addr); + _allocator[nr]->free((void *)(addr - 1)); + } + + size_t slab_size(void const *a) + { + using namespace Genode; + addr_t *addr =(addr_t *)a; + + unsigned nr = _slab_index(&addr); + size_t size = 1 << (SLAB_START_LOG2 + nr); + size -= (addr_t)a - (addr_t)(addr - 1); + return size; + } + + Genode::addr_t phys_addr(void *a) + { + return _back_allocator->phys_addr((addr_t)a); + } + + /** + * Belongs given address to this allocator + */ + bool inside(addr_t const addr) const { return (addr > _start) && (addr <= _end); } + + /** + * Cached memory allocator + */ + static Malloc *mem() + { + static Slab_backend_alloc _b(true); + static Malloc _m(&_b, true); + return &_m; + } +}; + + +/************************************* + ** Memory allocation, linux/slab.h ** + *************************************/ + +void *kmalloc(size_t size, gfp_t flags) +{ + void *addr = Malloc::mem()->alloc(size); + + unsigned long a = (unsigned long)addr; + + if (a & 0x3) + PERR("Unaligned kmalloc %lx", a); + +// PDBG("Kmalloc: [%lx-%lx) from %p", a, a + size, __builtin_return_address(0)); + return addr; +} + + +void *kzalloc(size_t size, gfp_t flags) +{ + void *addr = kmalloc(size, flags); + if (addr) + Genode::memset(addr, 0, size); + + //PDBG("Kmalloc: [%lx-%lx) from %p", (unsigned)addr, (unsigned)addr + size, __builtin_return_address(0)); + return addr; +} + + +void *kcalloc(size_t n, size_t size, gfp_t flags) +{ + if (size != 0 && n > ~0UL / size) + return 0; + + return kzalloc(n * size, flags); +} + +void kfree(const void *p) +{ + if (Malloc::mem()->inside((Genode::addr_t)p)) + Malloc::mem()->free(p); + else + PWRN("%p is not within our memory range called from %p", + p, __builtin_return_address(0)); +} + + +void *kmalloc_node_track_caller(size_t size, gfp_t flags, int node) +{ + return kmalloc(size, 0); +} + + +void *kzalloc_node(size_t size, gfp_t flags, int node) +{ + return kzalloc(size, 0); +} + +size_t ksize(const void *p) +{ + if (!(Malloc::mem()->inside((Genode::addr_t)p))) { + PDBG("%p not in slab allocator", p); + return 0; + } + + size_t size = Malloc::mem()->slab_size(p); + return size; +} + + +/******************** + ** linux/string.h ** + ********************/ + +char *strcpy(char *to, const char *from) +{ + char *save = to; + for (; (*to = *from); ++from, ++to); + return(save); +} + + +char *strchr(const char *p, int ch) +{ + char c; + c = ch; + for (;; ++p) { + if (*p == c) + return ((char *)p); + if (*p == '\0') + break; + } + + return 0; +} + +char *strnchr(const char *p, size_t count, int ch) +{ + char c; + c = ch; + for (; count; ++p, count--) { + if (*p == c) + return ((char *)p); + if (*p == '\0') + break; + } + + return 0; +} + +size_t strnlen(const char *s, size_t maxlen) +{ + size_t c; + for (c = 0; c < maxlen; c++) + if (!s[c]) + return c; + + return maxlen; +} + +size_t strlen(const char *s) { return Genode::strlen(s); } +int strcmp(const char *s1, const char *s2) { return Genode::strcmp(s1, s2); } +int strncmp(const char *s1, const char *s2, size_t len) { + return Genode::strcmp(s1, s2, len); } + +int memcmp(const void *p0, const void *p1, size_t size) { + return Genode::memcmp(p0, p1, size); } + + + +int snprintf(char *str, size_t size, const char *format, ...) +{ + va_list list; + va_start(list, format); + + Genode::String_console sc(str, size); + + sc.vprintf(format, list); + + va_end(list); + + return sc.len(); +} + + +size_t strlcpy(char *dest, const char *src, size_t size) +{ + size_t ret = strlen(src); + + if (size) { + size_t len = (ret >= size) ? size - 1 : ret; + Genode::memcpy(dest, src, len); + dest[len] = '\0'; + } + return ret; +} + + +void *kmemdup(const void *src, size_t len, gfp_t gfp) +{ + void *ptr = kmalloc(len, gfp); + Genode::memcpy(ptr, src, len); + return ptr; +} + + +void *genode_memcpy(void *d, const void *s, size_t n) +{ + return Genode::memcpy(d, s, n); +} + + +/****************** + ** linux/log2.h ** + ******************/ + +unsigned long ilog2(unsigned long n) { return Genode::log2(n); } + + +/******************* + ** linux/sched.h ** + *******************/ + +extern "C" void __wait_event() +{ + Genode::Signal s = Net::Env::receiver()->wait_for_signal(); + static_cast(s.context())->dispatch(s.num()); +} + + +long schedule_timeout_uninterruptible(signed long timeout) +{ + return schedule_timeout(timeout); +} + + +signed long schedule_timeout(signed long timeout) +{ + long start = jiffies; + __wait_event(); + timeout -= jiffies - start; + return timeout < 0 ? 0 : timeout; +} + +void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) +{ + __wait_event(); +} + + +/****************** + ** linux/time.h ** + ******************/ + +unsigned long get_seconds(void) +{ + return jiffies / HZ; +} + +/***************** + ** linux/gfp.h ** + *****************/ + +class Avl_page : public Genode::Avl_node +{ + private: + + Genode::addr_t _addr; + Genode::size_t _size; + struct page *_page; + + public: + + Avl_page(Genode::size_t size) : _size(size) + { + _addr =(Genode::addr_t)kmalloc(size, 0); + if (!_addr) + throw -1; + + _page = (struct page *) kzalloc(sizeof(struct page), 0); + if (!_page) { + kfree((void *)_addr); + throw -2; + } + + _page->addr = (void *)_addr; + atomic_set(&_page->_count, 1); + + dde_kit_log(DEBUG_SLAB, "alloc page: %p addr: %lx-%lx", _page, _addr, _addr + size); + } + + virtual ~Avl_page() + { + kfree((void *)_addr); + kfree((void *)_page); + } + + struct page* page() { return _page; } + + bool higher(Avl_page *c) + { + return c->_addr > _addr; + } + + Avl_page *find_by_address(Genode::addr_t addr) + { + if (addr >= _addr && addr < _addr + _size) + return this; + + bool side = addr > _addr; + Avl_page *c = Avl_node::child(side); + return c ? c->find_by_address(addr) : 0; + } +}; + +static Genode::Avl_tree tree; + +struct page *alloc_pages(gfp_t gfp_mask, unsigned int order) +{ + Avl_page *p; + try { + p = (Avl_page *)new (Genode::env()->heap()) Avl_page(PAGE_SIZE << order); + tree.insert(p); + } catch (...) { return 0; } + + return p->page(); +} + + +/**************** + ** linux/mm.h ** + ****************/ + +struct page *virt_to_head_page(const void *x) +{ + Avl_page *p = tree.first()->find_by_address((Genode::addr_t)x); + dde_kit_log(DEBUG_SLAB, "virt_to_head_page: %p page %p\n", x,p ? p->page() : 0); + + return p ? p->page() : 0; +} + + +void put_page(struct page *page) +{ + if (!atomic_dec_and_test(&page->_count)) + return; + + dde_kit_log(DEBUG_SLAB, "put_page: %p", page); + Avl_page *p = tree.first()->find_by_address((Genode::addr_t)page->addr); + + tree.remove(p); + destroy(Genode::env()->heap(), p); +} + + diff --git a/dde_linux/src/lib/lxip/nic_handler.cc b/dde_linux/src/lib/lxip/nic_handler.cc new file mode 100644 index 000000000..52c9953f7 --- /dev/null +++ b/dde_linux/src/lib/lxip/nic_handler.cc @@ -0,0 +1,148 @@ +#include +#include +#include + +#include +#include +#include + +enum { + MAC_LEN = 17, + ETH_ALEN = 6, +}; + +namespace Net { + class Nic; +} + + +class Net::Nic : public Net::Packet_handler +{ + private: + + enum { + PACKET_SIZE = ::Nic::Packet_allocator::DEFAULT_PACKET_SIZE, + BUF_SIZE = ::Nic::Session::QUEUE_SIZE * PACKET_SIZE, + }; + + ::Nic::Packet_allocator _tx_block_alloc; + ::Nic::Connection _nic; + + public: + + Nic() + : _tx_block_alloc(Genode::env()->heap()), + _nic(&_tx_block_alloc, BUF_SIZE, BUF_SIZE) + { + _nic.rx_channel()->sigh_ready_to_ack(_sink_ack); + _nic.rx_channel()->sigh_packet_avail(_sink_submit); + _nic.tx_channel()->sigh_ack_avail(_source_ack); + _nic.tx_channel()->sigh_ready_to_submit(_source_submit); + } + + /****************************** + ** Packet_handler interface ** + ******************************/ + + Packet_stream_sink< ::Nic::Session::Policy> * sink() { + return _nic.rx(); } + + Packet_stream_source< ::Nic::Session::Policy> * source() { + return _nic.tx(); } + + static Nic *nic() + { + static Nic _net_nic; + return &_net_nic; + } + + static ::Nic::Connection *n() + { + return &nic()->_nic; + } + +}; + + +Net::Packet_handler::Packet_handler() +: _sink_ack(*Net::Env::receiver(), *this, &Packet_handler::_ready_to_ack), + _sink_submit(*Net::Env::receiver(), *this, &Packet_handler::_packet_avail), + _source_ack(*Net::Env::receiver(), *this, &Packet_handler::_ack_avail), + _source_submit(*Net::Env::receiver(), *this, &Packet_handler::_ready_to_submit) +{ } + + +void Net::Packet_handler::_ack_avail(unsigned) +{ + while (source()->ack_avail()) + source()->release_packet(source()->get_acked_packet()); +} + + +void Net::Packet_handler::_ready_to_ack(unsigned num) +{ + _packet_avail(num); +} + + +void Net::Packet_handler::_packet_avail(unsigned) +{ + using namespace Net; + enum { MAX_PACKETS = 50 }; + + int count = 0; + while(Nic::n()->rx()->packet_avail() && + Nic::n()->rx()->ready_to_ack() && + ++count < MAX_PACKETS) { + + Packet_descriptor p = Nic::n()->rx()->get_packet(); + net_driver_rx(Net::Nic::n()->rx()->packet_content(p), p.size()); + Nic::n()->rx()->acknowledge_packet(p); + } + + if (count == MAX_PACKETS) + _sink_submit.submit(1); + //Genode::Signal_transmitter(_sink_submit).submit(); +} + + +static void snprint_mac(unsigned char *buf, unsigned char *mac) +{ + for (int i = 0; i < ETH_ALEN; i++) { + Genode::snprintf((char *)&buf[i * 3], 3, "%02x", mac[i]); + if ((i * 3) < MAC_LEN) + buf[(i * 3) + 2] = ':'; + } + + buf[MAC_LEN] = 0; +} + + +void net_mac(void* mac, unsigned long size) +{ + unsigned char str[MAC_LEN + 1]; + using namespace Genode; + + Nic::Mac_address m = Net::Nic::n()->mac_address(); + Genode::memcpy(mac, &m.addr, min(sizeof(m.addr), (size_t)size)); + + snprint_mac(str, (unsigned char *)m.addr); + PINF("Received mac: %s", str); +} + + +int net_tx(void* addr, unsigned long len) +{ + try { + Packet_descriptor packet = Net::Nic::n()->tx()->alloc_packet(len); + void* content = Net::Nic::n()->tx()->packet_content(packet); + + Genode::memcpy((char *)content, addr, len); + Net::Nic::n()->tx()->submit_packet(packet); + + return 0; + /* 'Packet_alloc_failed' */ + } catch(...) { + return 1; + } +} diff --git a/dde_linux/src/lib/lxip/socket.c b/dde_linux/src/lib/lxip/socket.c new file mode 100644 index 000000000..f4a02cf06 --- /dev/null +++ b/dde_linux/src/lib/lxip/socket.c @@ -0,0 +1,115 @@ +/** + * \brief BSD style socket helpers + * \author Sebastian Sumpf + * \date 2013-08-28 + */ + +/* + * 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 +#include +#include + +#include + +static const struct net_proto_family *net_families[NPROTO]; + + +int sock_register(const struct net_proto_family *ops) +{ + if (ops->family >= NPROTO) { + printk("protocol %d >= NPROTO (%d)\n", ops->family, NPROTO); + return -ENOBUFS; + } + + net_families[ops->family] = ops; + pr_info("NET: Registered protocol family %d\n", ops->family); + return 0; +} + + +struct socket *sock_alloc(void) +{ + return (struct socket *)kmalloc(sizeof(struct socket), 0); +} + + +int sock_create_lite(int family, int type, int protocol, struct socket **res) + +{ + struct socket *sock = sock_alloc(); + + if (!sock) + return -ENOMEM; + + sock->type = type; + *res = sock; + return 0; +} + + +int sock_create_kern(int family, int type, int proto, + struct socket **res) +{ + struct socket *sock; + const struct net_proto_family *pf; + int err; + + if (family < 0 || family > NPROTO) + return -EAFNOSUPPORT; + + if (type < 0 || type > SOCK_MAX) + return -EINVAL; + + pf = net_families[family]; + + if (!pf) { + printk("No protocol found for family %d\n", family); + return -ENOPROTOOPT; + } + + if (!(sock = (struct socket *)kzalloc(sizeof(struct socket), 0))) { + printk("Could not allocate socket\n"); + return -ENFILE; + } + + sock->type = type; + + err = pf->create(&init_net, sock, proto, 1); + if (err) { + kfree(sock); + return err; + } + + *res = sock; + + return 0; +} + + +int socket_check_state(struct socket *socket) +{ + if (socket->sk->sk_state == TCP_CLOSE_WAIT) + return -EINTR; + + return 0; +} + + +void log_sock(struct socket *socket) +{ + printk("\nNEW socket %p sk %p fsk %x &sk %p &fsk %p\n\n", + socket, socket->sk, socket->flags, &socket->sk, &socket->flags); +} + + +static void sock_init(void) +{ + skb_init(); +} + +core_initcall(sock_init); diff --git a/dde_linux/src/lib/lxip/socket_handler.cc b/dde_linux/src/lib/lxip/socket_handler.cc new file mode 100644 index 000000000..5b47a87e4 --- /dev/null +++ b/dde_linux/src/lib/lxip/socket_handler.cc @@ -0,0 +1,630 @@ +/** + * \brief Front-end and glue to IP stack + * \author Sebastian Sumpf + * \date 2013-09-26 + */ + +/* + * 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 +#include +#include +#include + +#include +#include +#include +#include + +extern "C" void wait_for_continue(); + +static const bool verbose = false; + + +namespace Linux { + extern "C" { + #include + #include + #include + + extern int sock_setsockopt(struct socket *sock, int level, + int op, char __user *optval, + unsigned int optlen); + extern int sock_getsockopt(struct socket *sock, int level, + int op, char __user *optval, + int __user *optlen); + } +} + +namespace Net +{ + class Socketcall; + + enum Opcode { OP_SOCKET = 0, OP_CLOSE = 1, OP_BIND = 2, OP_LISTEN = 3, + OP_ACCEPT = 4, OP_POLL = 5, OP_RECV = 6, OP_CONNECT = 7, + OP_SEND = 8, OP_SETOPT = 9, OP_GETOPT = 10, OP_GETNAME = 11, + OP_PEERNAME = 12, OP_IOCTL = 13, OP_SHUTDOWN = 14 }; + + struct Call + { + Opcode opcode; + Lxip::Handle handle; + + union + { + struct + { + Lxip::Type type; + } socket; + struct + { + int backlog; + } listen; + struct + { + void *addr; + Lxip::uint32_t *len; + } accept; + struct + { + mutable void *buf; + Lxip::size_t len; + int flags; + void *addr; + Lxip::uint32_t *addr_len; + } msg; + struct + { + int level; + int optname; + const void *optval; + Lxip::uint32_t optlen; + int *optlen_ptr; + } sockopt; + struct { + bool block; + } poll; + struct { + int request; + unsigned long arg; + } ioctl; + struct { + int how; + } shutdown; + }; + + struct Linux::sockaddr_storage addr; + Lxip::uint32_t addr_len; + }; + + union Result + { + int err; + Lxip::ssize_t len; + }; + +}; + + +class Net::Socketcall : public Genode::Signal_dispatcher_base, + public Genode::Signal_context_capability, + public Lxip::Socketcall, + public Genode::Thread<64 * 1024 * sizeof(Genode::addr_t)> +{ + private: + + Call _call; + Result _result; + Lxip::Handle _handle; + + Genode::Signal_transmitter _signal; + Genode::Semaphore _block; + + void _submit_and_block() + { + //_signal.submit(); /* global submit */ + submit(1); /* local submit */ + _block.down(); + } + + void _unblock() { _block.up(); } + + struct Linux::socket * call_socket() + { + return static_cast(_call.handle.socket); + } + + + Lxip::uint32_t _family_handler(Lxip::uint16_t family, void *addr) + { + using namespace Linux; + + if (!addr) + return 0; + + switch (family) + { + case AF_INET: + + struct sockaddr_in *in = (struct sockaddr_in *)addr; + struct sockaddr_in *out = (struct sockaddr_in *)&_call.addr; + + out->sin_family = family; + out->sin_port = in->sin_port; + out->sin_addr.s_addr = in->sin_addr.s_addr; + + return sizeof(struct sockaddr_in); + } + + return 0; + } + + /****************************************** + ** Glue interface to Linux TCP/IP stack ** + ******************************************/ + + void _do_accept() + { + using namespace Linux; + + struct socket *sock = call_socket(); + struct socket *new_sock = (struct socket *)kzalloc(sizeof(struct socket), 0); + + _handle.socket = 0; + + if (!new_sock) + return; + + new_sock->type = sock->type; + new_sock->ops = sock->ops; + + if ((sock->ops->accept(sock, new_sock, 0)) < 0) { + kfree(new_sock); + return; + } + + _handle.socket = static_cast(new_sock); + + + if (!_call.accept.addr) + return; + + int len; + if ((new_sock->ops->getname(new_sock, (struct sockaddr *)&_call.addr, + &len, 2)) < 0) + return; + + *_call.accept.len = min(*_call.accept.len, len); + Genode::memcpy(_call.accept.addr, &_call.addr, *_call.accept.len); + } + + void _do_bind() + { + struct Linux::socket *sock = call_socket(); + + _result.err = sock->ops->bind(sock, (struct Linux::sockaddr *) &_call.addr, + _call.addr_len); + } + + void _do_close() + { + using namespace Linux; + + struct socket *s = call_socket(); + if (s->ops) + s->ops->release(s); + + kfree(s); + } + + void _do_connect() + { + Linux::socket *sock = call_socket(); + + //XXX: have a look at the file flags + _result.err = sock->ops->connect(sock, (struct Linux::sockaddr *) &_call.addr, + _call.addr_len, 0); + } + + void _do_getname(int peer) + { + int len = sizeof(Linux::sockaddr_storage); + _result.err = call_socket()->ops->getname(call_socket(), + (struct Linux::sockaddr *)&_call.addr, + &len, peer); + + *_call.accept.len = Linux::min(*_call.accept.len, len); + Genode::memcpy(_call.accept.addr, &_call.addr, *_call.accept.len); + } + + + void _do_getopt() + { + _result.err = Linux::sock_getsockopt(call_socket(), _call.sockopt.level, + _call.sockopt.optname, + (char *)_call.sockopt.optval, + _call.sockopt.optlen_ptr); + } + + void _do_ioctl() + { + _result.err = call_socket()->ops->ioctl(call_socket(), + _call.ioctl.request, + _call.ioctl.arg); + } + + void _do_listen() + { + _result.err = call_socket()->ops->listen(call_socket(), + _call.listen.backlog); + } + + void _do_poll() + { + using namespace Linux; + struct socket *sock = call_socket(); + enum { + POLLIN_SET = (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR), + POLLOUT_SET = (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR), + POLLEX_SET = (POLLPRI) + }; + + /* + * Set socket wait queue to one so we can block poll in 'tcp_poll -> poll_wait' + */ + set_sock_wait(sock, _call.poll.block ? 1 : 0); + int mask =sock->ops->poll(0, sock, 0); + set_sock_wait(sock, 0); + + _result.err = 0; + if (mask & POLLIN_SET) + _result.err |= Lxip::POLLIN; + if (mask & POLLOUT_SET) + _result.err |= Lxip::POLLOUT; + if (mask & POLLEX_SET) + _result.err |= Lxip::POLLEX; + } + + void _do_recv() + { + using namespace Linux; + struct msghdr msg; + struct iovec iov; + + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_iovlen = 1; + msg.msg_iov = &iov; + iov.iov_len = _call.msg.len; + iov.iov_base = _call.msg.buf; + msg.msg_name = _call.addr_len ? &_call.addr : 0; + msg.msg_namelen = _call.addr_len; + msg.msg_flags = 0; + + if (_call.handle.non_block) + msg.msg_flags |= MSG_DONTWAIT; + + //XXX: check for non-blocking flag + _result.err = call_socket()->ops->recvmsg(0, call_socket(), &msg, + _call.msg.len, + _call.msg.flags); + + if (_call.msg.addr) { + *_call.msg.addr_len = min(*_call.msg.addr_len, msg.msg_namelen); + Genode::memcpy(_call.msg.addr, &_call.addr, *_call.msg.addr_len); + } + } + + void _do_send() + { + using namespace Linux; + struct msghdr msg; + struct iovec iov; + + _result.err = socket_check_state(call_socket()); + if (_result.err < 0) + return; + + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_iovlen = 1; + msg.msg_iov = &iov; + iov.iov_len = _call.msg.len; + iov.iov_base = _call.msg.buf; + msg.msg_name = _call.addr_len ? &_call.addr : 0; + msg.msg_namelen = _call.addr_len; + msg.msg_flags = _call.msg.flags; + + if (_call.handle.non_block) + msg.msg_flags |= MSG_DONTWAIT; + + _result.err = call_socket()->ops->sendmsg(0, call_socket(), &msg, + _call.msg.len); + } + + void _do_setopt() + { + _result.err = Linux::sock_setsockopt(call_socket(), _call.sockopt.level, + _call.sockopt.optname, + (char *)_call.sockopt.optval, + _call.sockopt.optlen); + } + + void _do_shutdown() + { + _result.err = call_socket()->ops->shutdown(call_socket(), + _call.shutdown.how); + } + + void _do_socket() + { + using namespace Linux; + int type = _call.socket.type == Lxip::TYPE_STREAM ? SOCK_STREAM : + SOCK_DGRAM; + + struct socket *s = (struct socket *)kzalloc(sizeof(struct socket), 0); + + if (!sock_create_kern(AF_INET, type, 0, &s)) { + _handle.socket = static_cast(s); + return; + } + + _handle.socket = 0; + kfree(s); + } + + public: + + Socketcall() + : Thread("socketcall"), + _signal(Genode::Signal_context_capability(Env::receiver()->manage(this))) + { + start(); + } + + + void entry() + { + while (true) { + Genode::Signal s = Net::Env::receiver()->wait_for_signal(); + static_cast(s.context())->dispatch(s.num()); + } + } + + /*********************** + ** Signal dispatcher ** + ***********************/ + + void dispatch(unsigned num) + { + if (verbose) + PDBG("SOCKET dispatch %u", _call.opcode); + + switch (_call.opcode) { + + case OP_ACCEPT : _do_accept(); break; + case OP_BIND : _do_bind(); break; + case OP_CLOSE : _do_close(); break; + case OP_CONNECT : _do_connect(); break; + case OP_GETNAME : _do_getname(0); break; + case OP_GETOPT : _do_getopt(); break; + case OP_IOCTL : _do_ioctl(); break; + case OP_PEERNAME : _do_getname(1); break; + case OP_LISTEN : _do_listen(); break; + case OP_POLL : _do_poll(); break; + case OP_RECV : _do_recv(); break; + case OP_SEND : _do_send(); break; + case OP_SETOPT : _do_setopt(); break; + case OP_SHUTDOWN : _do_shutdown(); break; + case OP_SOCKET : _do_socket(); break; + + default: + _handle.socket = 0; + PWRN("Unkown opcode: %u\n", _call.opcode); + } + + _unblock(); + } + + + /************************** + ** Socketcall interface ** + **************************/ + + Lxip::Handle accept(Lxip::Handle h, void *addr, Lxip::uint32_t *len) + { + _call.opcode = OP_ACCEPT; + _call.handle = h; + _call.accept.addr = addr; + _call.accept.len = len; + + _submit_and_block(); + + return _handle; + } + + int bind(Lxip::Handle h, Lxip::uint16_t family, void *addr) + { + _call.opcode = OP_BIND; + _call.handle = h; + _call.addr_len = _family_handler(family, addr); + + _submit_and_block(); + + return _result.err; + } + + void close(Lxip::Handle h) + { + _call.opcode = OP_CLOSE; + _call.handle = h; + + _submit_and_block(); + } + + int connect(Lxip::Handle h, Lxip::uint16_t family, void *addr) + { + _call.opcode = OP_CONNECT; + _call.handle = h; + _call.addr_len = _family_handler(family, addr); + + _submit_and_block(); + + return _result.err; + } + + int getpeername(Lxip::Handle h, void *addr, Lxip::uint32_t *len) + { + _call.opcode = OP_PEERNAME; + _call.handle = h; + _call.accept.len = len; + _call.accept.addr = addr; + + _submit_and_block(); + + return _result.err; + } + + int getsockname(Lxip::Handle h, void *addr, Lxip::uint32_t *len) + { + _call.opcode = OP_GETNAME; + _call.handle = h; + _call.accept.len = len; + _call.accept.addr = addr; + + _submit_and_block(); + + return _result.err; + } + + int getsockopt(Lxip::Handle h, int level, int optname, + void *optval, int *optlen) + { + _call.opcode = OP_GETOPT; + _call.handle = h; + _call.sockopt.level = level; + _call.sockopt.optname = optname; + _call.sockopt.optval = optval; + _call.sockopt.optlen_ptr = optlen; + + _submit_and_block(); + + return _result.err; + } + + int ioctl(Lxip::Handle h, int request, char *arg) + { + _call.opcode = OP_IOCTL; + _call.handle = h; + _call.ioctl.request = request; + _call.ioctl.arg = (unsigned long)arg; + + _submit_and_block(); + + return _result.err; + } + + int listen(Lxip::Handle h, int backlog) + { + _call.opcode = OP_LISTEN; + _call.handle = h; + _call.listen.backlog = backlog; + + _submit_and_block(); + + return _result.err; + } + + int poll(Lxip::Handle h, bool block) + { + _call.opcode = OP_POLL; + _call.handle = h; + _call.poll.block = block; + + _submit_and_block(); + + return _result.err; + } + + Lxip::ssize_t recv(Lxip::Handle h, void *buf, Lxip::size_t len, int flags, + Lxip::uint16_t family, void *addr, + Lxip::uint32_t *addr_len) + { + _call.opcode = OP_RECV; + _call.handle = h; + _call.msg.buf = buf; + _call.msg.len = len; + _call.msg.addr = addr; + _call.msg.addr_len = addr_len; + _call.msg.flags = flags; + _call.addr_len = _family_handler(family, addr); + + _submit_and_block(); + + return _result.len; + } + + Lxip::ssize_t send(Lxip::Handle h, const void *buf, Lxip::size_t len, int flags, + Lxip::uint16_t family, void *addr) + { + _call.opcode = OP_SEND; + _call.handle = h; + _call.msg.buf = (void *)buf; + _call.msg.len = len; + _call.msg.flags = flags; + _call.addr_len = _family_handler(family, addr); + + _submit_and_block(); + + return _result.len; + } + + int setsockopt(Lxip::Handle h, int level, int optname, + const void *optval, Lxip::uint32_t optlen) + { + _call.opcode = OP_SETOPT, + _call.handle = h; + _call.sockopt.level = level; + _call.sockopt.optname = optname; + _call.sockopt.optval = optval; + _call.sockopt.optlen = optlen; + + _submit_and_block(); + + return _result.err; + } + + int shutdown(Lxip::Handle h, int how) + { + _call.opcode = OP_SHUTDOWN; + _call.handle = h; + _call.shutdown.how = how; + + _submit_and_block(); + + return _result.err; + } + + Lxip::Handle socket(Lxip::Type type) + { + _call.opcode = OP_SOCKET; + _call.socket.type = type; + + _submit_and_block(); + + return _handle; + } +}; + + +Lxip::Socketcall & Lxip::init() +{ + static int init = lxip_init(); + static Net::Socketcall socketcall; + + return socketcall; +} diff --git a/dde_linux/src/lib/lxip/timer_handler.cc b/dde_linux/src/lib/lxip/timer_handler.cc new file mode 100644 index 000000000..8fc3888a5 --- /dev/null +++ b/dde_linux/src/lib/lxip/timer_handler.cc @@ -0,0 +1,145 @@ +/* + * \brief Signal context for timer events + * \author Sebastian Sumpf + * \date 2012-05-23 + */ + +/* + * 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. + */ + +#include +#include + +#include +#include + +extern "C" { +#include +} + +static void handler(void *timer); + +/** + * Signal context for time-outs + */ +class Timer_context +{ + private: + + timer_list *_timer; /* Linux timer */ + dde_kit_timer *_dde_timer; /* DDE kit timer */ + Genode::Signal_dispatcher _dispatcher; + + /* call timer function */ + void _handle(unsigned) { _timer->function(_timer->data); } + + public: + + Timer_context(timer_list *timer) + : _timer(timer), _dde_timer(0), + _dispatcher(*Net::Env::receiver(), *this, &Timer_context::_handle) {} + + /* schedule next timeout */ + void schedule(unsigned long expires) + { + if (!_dde_timer) + _dde_timer = dde_kit_timer_add(handler, this, expires); + else + dde_kit_timer_schedule_absolute(_dde_timer, expires); + } + + /** + * Return true if timer is pending + */ + bool pending() const + { + return _dde_timer ? dde_kit_timer_pending(_dde_timer) : false; + } + + /** + * Return internal signal cap + */ + Genode::Signal_context_capability cap() const { return _dispatcher; } + void submit() { _dispatcher.submit(1); } + + /** + * Convert 'timer_list' to 'Timer_conext' + */ + static Timer_context *to_ctx(timer_list const *timer) { + return static_cast(timer->timer); } + + void remove() + { + if (_dde_timer) + dde_kit_timer_del(_dde_timer); + + _dde_timer = 0; + } +}; + + +/** + * C handler for DDE timer interface + */ +static void handler(void *timer) +{ + Timer_context *t = static_cast(timer); + t->submit(); + /* set context and submit + Genode::Signal_transmitter transmitter(t->cap()); + transmitter.submit(); */ +} + + +/******************* + ** linux/timer.h ** + *******************/ + +void init_timer(struct timer_list *timer) { + timer->timer = (void *) new (Genode::env()->heap()) Timer_context(timer); } + + +void add_timer(struct timer_list *timer) +{ + BUG_ON(timer_pending(timer)); + mod_timer(timer, timer->expires); +} + + +int mod_timer(struct timer_list *timer, unsigned long expires) +{ + dde_kit_log(DEBUG_TIMER, "Timer: %p j: %lu ex: %lu func %p", + timer, jiffies, expires, timer->function); + Timer_context::to_ctx(timer)->schedule(expires); + return 0; +} + + +void setup_timer(struct timer_list *timer,void (*function)(unsigned long), + unsigned long data) +{ + timer->function = function; + timer->data = data; + init_timer(timer); +} + + +int timer_pending(const struct timer_list * timer) +{ + bool pending = Timer_context::to_ctx(timer)->pending(); + dde_kit_log(DEBUG_TIMER, "Pending %p %u", timer, pending); + return pending; +} + + +int del_timer(struct timer_list *timer) +{ + dde_kit_log(DEBUG_TIMER, "Delete timer %p", timer); + Timer_context::to_ctx(timer)->remove(); + return 0; +} + diff --git a/ports/run/netperf.inc b/ports/run/netperf.inc index e9216713d..a07667de7 100644 --- a/ports/run/netperf.inc +++ b/ports/run/netperf.inc @@ -55,6 +55,7 @@ lappend_if $use_platform_driver build_components drivers/platform lappend_if $use_nic_bridge build_components server/nic_bridge lappend_if [have_spec acpi] build_components drivers/acpi lappend_if [have_spec pci] build_components drivers/pci/device_pd +lappend_if [have_spec gpio] build_components drivers/gpio build $build_components @@ -96,6 +97,13 @@ append_if $use_platform_driver config { } +append_if [have_spec gpio] config { + + + + + } + append_if $use_nic_bridge config { @@ -196,6 +204,7 @@ lappend_if $use_nic_bridge boot_modules nic_bridge lappend_if $use_platform_driver boot_modules platform_drv lappend_if [have_spec acpi] boot_modules acpi_drv lappend_if [have_spec pci] boot_modules pci_drv +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 lappend_if [have_spec nova] boot_modules pci_device_pd