diff --git a/repos/dde_linux/lib/mk/spec/arm_64/wireguard.mk b/repos/dde_linux/lib/mk/spec/arm_64/wireguard.mk new file mode 100644 index 0000000000..5becda2d3f --- /dev/null +++ b/repos/dde_linux/lib/mk/spec/arm_64/wireguard.mk @@ -0,0 +1,23 @@ +# +# For documentation see $(REP_DIR)/lib/mk/wireguard.inc . +# + +PRG_DIR := $(REP_DIR)/src/app/wireguard/spec/arm_64 +GEN_PRG_DIR := $(PRG_DIR)/../.. + +SRC_C += arch/arm64/kernel/smp.c +SRC_C += kernel/smp.c +SRC_C += arch/arm64/kernel/cpufeature.c + +vpath arch/arm64/kernel/cpufeature.c $(GEN_PRG_DIR)/lx_emul/shadow +vpath arch/arm64/kernel/smp.c $(REP_DIR)/src/lib/lx_emul/shadow +vpath kernel/smp.c $(REP_DIR)/src/lib/lx_emul/shadow + +SRC_S += arch/arm64/crypto/poly1305-core.S + +arch/arm64/crypto/poly1305-core.S: + $(VERBOSE)perl $(LX_SRC_DIR)/arch/arm64/crypto/poly1305-armv8.pl > $@ + +CC_OPT_arch/arm64/crypto/poly1305-core += -Dpoly1305_init=poly1305_init_arm64 + +include $(REP_DIR)/lib/mk/wireguard.inc diff --git a/repos/dde_linux/lib/mk/spec/x86_64/wireguard.mk b/repos/dde_linux/lib/mk/spec/x86_64/wireguard.mk new file mode 100644 index 0000000000..e51e4e805b --- /dev/null +++ b/repos/dde_linux/lib/mk/spec/x86_64/wireguard.mk @@ -0,0 +1,12 @@ +# +# For documentation see $(REP_DIR)/lib/mk/wireguard.inc . +# + +PRG_DIR := $(REP_DIR)/src/app/wireguard/spec/x86_64 + +SRC_S += arch/x86/crypto/poly1305-x86_64-cryptogams.S + +arch/x86/crypto/poly1305-x86_64-cryptogams.S: + perl $(LX_SRC_DIR)/arch/x86/crypto/poly1305-x86_64-cryptogams.pl > $@ + +include $(REP_DIR)/lib/mk/wireguard.inc diff --git a/repos/dde_linux/lib/mk/wireguard.inc b/repos/dde_linux/lib/mk/wireguard.inc new file mode 100644 index 0000000000..da0af3d3ce --- /dev/null +++ b/repos/dde_linux/lib/mk/wireguard.inc @@ -0,0 +1,61 @@ +# +# This library is for avoiding clashes between Linux and Genode includes. +# If we were to compile all the *.c files of this library directly with the +# Wireguard target there would be only one INC_DIR applied to *.cc files as +# well as to *.c files. Some Genode headers, however (e.g. 'net/udp.h' or +# 'net/dhcp.h') exist with the same include identifier in both Linux and +# Genode, and we would have the problem that we want the Linux variant in *.c +# files and the Genode variant in *.cc files. Therefore, we create two +# dedicated INC_DIR settings (that of the library and that of the target). +# + +GEN_PRG_DIR := $(PRG_DIR)/../.. + +SRC_C += $(notdir $(wildcard $(PRG_DIR)/generated_dummies.c)) +SRC_C += dummies.c +SRC_C += dummies_arch.c +SRC_C += lx_emul.c +SRC_C += wireguard.c +SRC_C += genode_c_api_arch.c + +vpath lx_emul/alloc.cc $(GEN_PRG_DIR) +vpath lx_kit/memory.cc $(GEN_PRG_DIR) +vpath wireguard.c $(GEN_PRG_DIR)/genode_c_api +vpath %.c $(PRG_DIR) +vpath %.c $(GEN_PRG_DIR) + +INC_DIR += $(PRG_DIR) +INC_DIR += $(GEN_PRG_DIR) + +LIBS += lx_emul virt_linux_generated + +CC_OPT_wireguard += -DKBUILD_MODFILE='"wireguard"' \ + -DKBUILD_BASENAME='"wireguard"' \ + -DKBUILD_MODNAME='"wireguard"' +CC_OPT_lx_emul += -DKBUILD_MODFILE='"lx_emul"' \ + -DKBUILD_BASENAME='"lx_emul"' \ + -DKBUILD_MODNAME='"lx_emul"' + +# +# The lx_emul Makefiles have a generic mechanism for defining the +# KBUILD_MODNAME for each Linux unit to be the filename of that unit +# (without suffix). However, some Wireguard units expect +# KBUILD_MODNAME to be the same for all Wireguard units. +# Therefore, we do a pattern substition on the CC_OPT_* variables of +# those units, changing their KBUILD_MODNAME def to "wireguard". +# + +OBJECTS_TO_FIX_MODNAME_DEFS_FOR := \ + drivers/net/wireguard/device.o \ + drivers/net/wireguard/netlink.o + +define FIX_MODNAME_DEF = +CC_OPT_$(1) = $(patsubst -DKBUILD_MODNAME='"%"',-DKBUILD_MODNAME='"wireguard"',$(CC_OPT_$(1))) +endef + +.PHONY: fix_modname_defs +fix_modname_defs: + $(foreach file,$(OBJECTS_TO_FIX_MODNAME_DEFS_FOR), \ + $(eval $(call FIX_MODNAME_DEF,$(file:%.o=%)))) + +$(OBJECTS_TO_FIX_MODNAME_DEFS_FOR): fix_modname_defs diff --git a/repos/dde_linux/run/wg_fetchurl.run b/repos/dde_linux/run/wg_fetchurl.run new file mode 100644 index 0000000000..665e8e1490 --- /dev/null +++ b/repos/dde_linux/run/wg_fetchurl.run @@ -0,0 +1,419 @@ +# +# FetchURL downloading a file from a LightTPD server through a Wireguard VPN +# +# By default, the file is an short inline HTML file at lighttpd and downloaded +# into RAM in fetchurl. However, when the test is run with base-linux, +# lighttpd uses a file created by the host filled filled with zeroes and of +# customizable size and fetchurl downloads into the host FS, so the test can +# then check the MD5 sum of the file. +# + +if {[expr ![have_spec arm_64] && ![have_spec x86_64]]} { + puts "Run script is not supported on this platform." + exit 0 +} + +if {[have_spec linux]} { + set linux 1 + set not_linux 0 +} else { + set linux 0 + set not_linux 1 +} + +# +# Note that in the not_linux case, the file size is rounded +# down to a multiple of 100. +# +set file_size_in_bytes 1000000 + +create_boot_directory + +import_from_depot [depot_user]/src/libc \ + [depot_user]/src/libssh \ + [depot_user]/src/lighttpd \ + [depot_user]/src/openssl \ + [depot_user]/src/posix \ + [depot_user]/src/vfs \ + [depot_user]/src/vfs_lwip \ + [depot_user]/src/zlib + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + +append_if $linux config { + + + + + + + + + + + + + + + } + +append config { + + + + + + + + + 2019-07-04 12:00 + 01234567890123456789 + + + + + } + +append_if $linux config { + + } + +append_if $not_linux config { + + } + +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2000-01-01 00:00 + 0123456789012345678901234567890123456789 + + + + + +# lighttpd configuration +server.port = 80 +server.document-root = "/website" +server.event-handler = "select" +server.network-backend = "write" +server.upload-dirs = ( "/tmp" ) +server.modules = ("mod_openssl") +index-file.names = ( + "index.xhtml", "index.html", "index.htm" +) +mimetype.assign = ( + ".html" => "text/html", + ".htm" => "text/html" +) +$SERVER["socket"] == ":443" { + ssl.engine = "enable" + ssl.pemfile = "/etc/lighttpd/example.pem" +} + + +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4KHUZjDRew89c +wDlYPz9XFigcMDnDlHzdg2ByrGZIOUNYC5LH1QUK0TDbPP45Xx455niA0QY85dMQ +4DQx0Qk6+TDpVD3F2MYQgbIX6YkX9kgqX+jiHgsNzRD4KamNYmfUY+dJhlZEXWAF +uNSnRLvg4EH72AVKLLKiruGwkisW/AYU6dNE8iFOYL8Q75bBUADiQSDdD8vkpeXg +1NqxNyHPR6YRbA+vqcK0kbC8btKR9wG6m99OhTR4x3M87vtFFLNtJNEf54fYxi+L +1rljSqHbaXD+XJsVKgX+UlI1ZlYW4KqlMciMemkBp0CovCxLfsbMmkXAW2RONpkm ++sdO3CXFAgMBAAECggEAIKv00nqAVAuzP0ZPJivaZe3lYdLgfKVcXcRQGSgi4U9f +dkBfYxqU0W15mHvCspUAfM85s8jhrW4suwK739axJ4hMOCkc6Hvj78vCt+FT1C96 +cCIh4/PmjCVEjHJ/xTifKRwsTWwK5AgY4AsBl0dneabvremOTrGNY7VZDwVvpZz1 +qXkSNjQ63tZKj9cESO5ceGLzuBAG6JDDpqJM5fmdsQ36/QVz9Gogr8bXEWFM1TOo +lWVAPB/l6nqKurfMv+5th354+owv9CGKxqLBE1fujwE2VogBz7mkR/rnABOPU5ev +wQVLXoUkO2bI8Uvc28lChaiG6ihfdmNCmwoi56HFRQKBgQDj0WoIxiY7H42KV7Hh +uQZv/0aoQyjXuqJ7Vq0HdxOAxZr0GpSYgo3MTZWooI2AnAstPHXo0BsQr+XVijWm +xiDxMM4p9nrBzjEIHwyDaf62Pz/6lIPdenynLiEIOUbocJ3r0/3tCrY3U7fgjzYY +f9PZmXKEOOKdbVPyXG0OIJ/ADwKBgQDO8GkCdVGy/YB0X7ntqcBG0xgmDnKRmYpQ +X7Tb377AT2lzvftxaRVrx+UXtvFdy4xdrxjqHJCgOHT/fsAfjJlo7v1+KhTvE0pt +jCdJPLbzXJRwaISaeEaMJ/N8Vv/j2/YuoS5M5vh4NlWeO16HtF7N9V9cMEZ5iRW1 +9G/eWgOo6wKBgQCY6rn3xblnuhgxogd+ccmGZ50v2FST6WyiyV0/Q4hNyVXnP+g6 +LneriPBJzertRtChvpGOghGIs+jb2veESD1YZ+Aafp2LdTGoN98YXo9gGTiCpCmX +Al6lgOsfMAMOhnkaEKPC9ou0u3cTPk2bSEIVL1CUu/IwpW/RoIR7FR7ltQKBgQDA +RAmsqQfhPzqL5SzALclhhFuZcC7uLDOf/WvyJW37C000pjzp3/JxE2Y8pFKZDLc7 +i6WgTi3pTssVXtRt+5nFLtcC02Jjxg6OvXr6xphMf6XC0rjxM/KH4c6Npd9V+1Y9 +eK+l76rHNeRSgWKQvvqebO3On2O7I6yyQ4t0kTl5RQKBgQCbX1cTtNmNr6HNleXL +zfclKESSYy57uq3fQxhRrEE2ZNbemLOxEuoBCFYoMwpZEjC1GZyICrM7o5673/Ih +I0oZerUBmt2l8noZCQoITEa97bCbp2vIdHYnCf/H3Nf2qM329fc00kAmm7vUVRgM +4BqXnuFcAOuY68sgp9JArzK+EQ== +-----END PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDazCCAlOgAwIBAgIUYPOYXijLmMjjlgRCGHuZeyP0iPEwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCREUxEzARBgNVBAgMClNvbWUtU3RhdGUxDTALBgNVBAoM +BFRlc3QxEjAQBgNVBAMMCTEwLjAuMi41NTAeFw0yMDA1MTQxNDQ0MzlaFw00NzA5 +MzAxNDQ0MzlaMEUxCzAJBgNVBAYTAkRFMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0w +CwYDVQQKDARUZXN0MRIwEAYDVQQDDAkxMC4wLjIuNTUwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC4KHUZjDRew89cwDlYPz9XFigcMDnDlHzdg2ByrGZI +OUNYC5LH1QUK0TDbPP45Xx455niA0QY85dMQ4DQx0Qk6+TDpVD3F2MYQgbIX6YkX +9kgqX+jiHgsNzRD4KamNYmfUY+dJhlZEXWAFuNSnRLvg4EH72AVKLLKiruGwkisW +/AYU6dNE8iFOYL8Q75bBUADiQSDdD8vkpeXg1NqxNyHPR6YRbA+vqcK0kbC8btKR +9wG6m99OhTR4x3M87vtFFLNtJNEf54fYxi+L1rljSqHbaXD+XJsVKgX+UlI1ZlYW +4KqlMciMemkBp0CovCxLfsbMmkXAW2RONpkm+sdO3CXFAgMBAAGjUzBRMB0GA1Ud +DgQWBBQvSHuosL/SDn/8sKl0dpyPeFvOfjAfBgNVHSMEGDAWgBQvSHuosL/SDn/8 +sKl0dpyPeFvOfjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBR +sGYEuRwIU/tmAmTbniptItN9VE0NNj9QeKh+hKQ9cHvhxmlBlf5b7Vb2JaRZdy88 +kRIFKiNkyjgQVg+5KuEIcg17mHSal7zG+jIZ3c1bIpVCM4AjUe7EXl8LM4+dJ5sX +Bwpd34tUk2edOiT8R/dU7uesxCdeIQ2FfvKyrXca73nj+UTvFGXUk/9mWY8KAaYc +F/PWBhiZhJD4/dkUHJnrVtjpcqW2Io8bFmrMq2vfqQv+W2FZGCsHgXkAZO2E0jyQ +5eOrwzgWRtMc5PvoGvqQfefseaLs0fvSQdcPqfv88Eqk5NGTOCIW8/KEsBwFJuwa +EpA5DBBklj8UE2CdONvN +-----END CERTIFICATE----- + + + + } + +append_if $linux config { + + } + +if {$not_linux} { + + append config {} + for {set i 0} {$i < $file_size_in_bytes} {incr i 64} { + + # append 100 bytes of "0" + append config {0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000} + } + append config {} +} + +append config { + + + + + + + + + + + + + + + + + + + + +} + +install_config $config + +append targets { + core init timer server/nic_router app/wireguard server/report_rom + app/fetchurl } + +append boot_modules { + core init timer nic_router wireguard fetchurl report_rom curl.lib.so + ld.lib.so } + +if $linux { + + append targets { server/lx_fs } + append boot_modules { lx_fs } + + # create the lx_fs root of fetchurl where it will store the downloaded file + proc lx_fs_root {} { return [run_dir]/genode } + exec rm -rf [lx_fs_root]/fetchurl_fs + exec mkdir -p [lx_fs_root]/fetchurl_fs + + # create the lx_fs root of lighttpd and the downloadable file inside it + exec rm -rf [lx_fs_root]/lighttpd_fs + exec mkdir -p [lx_fs_root]/lighttpd_fs + exec head -c $file_size_in_bytes /dev/zero > [lx_fs_root]/lighttpd_fs/index.html +} + +build $targets + +build_boot_image $boot_modules + +append qemu_args "-nographic " + +# run the scenario till fetchurl succeeded to download the file +run_genode_until "fetchurl. exited with exit value 0.*\n" 60 + +if {$linux} { + + # check that the md5 sum of the downloaded file is correct + set lighttpd_index_md5 [exec md5sum [lx_fs_root]/lighttpd_fs/index.html] + set fetchurl_index_md5 [exec md5sum [lx_fs_root]/fetchurl_fs/index.html] + + puts "" + puts $lighttpd_index_md5 + puts $fetchurl_index_md5 + puts "MD5SUM of transferred files is correct" + + if {[string compare -length 32 $lighttpd_index_md5 $fetchurl_index_md5]} { + puts "" + puts "Error: MD5SUM of transferred files is incorrect" + puts "" + exit -1 + } +} diff --git a/repos/dde_linux/run/wg_lighttpd.run b/repos/dde_linux/run/wg_lighttpd.run new file mode 100644 index 0000000000..4310f4a88b --- /dev/null +++ b/repos/dde_linux/run/wg_lighttpd.run @@ -0,0 +1,293 @@ +# +# LightTPD server in a Wireguard VPN +# +# Once the scenario is running and DHCP is done, you can reach the server from +# your host system via 10.0.9.2:80 . The traffic is going through a host +# Wireguard device 'wg0' that puts it into an encrypted UDP tunnel towards the +# TAP device 'tap0' where it enters Qemu and reaches the inner Genode router +# at domain 'uplink'. The inner router port-forwards the traffic to its +# 'downlink' domain to which the tunnel side (10.0.3.2) of the Genode Wireguard +# component is connected . This component unpacks the original packets +# from the tunnel. The back side of the component is connected to the inner +# Genode router at domain 'uplink' and sends the plain packets unmodified a +# this connection. The routers IP identity in that domain is the Wireguard +# device IP, speak the VPN-internal IP 10.0.9.2 of the server. The inner +# router now forwards the different ports to the corresponding peers, in +# this case TCP port 80 to the LightTPD server (10.0.5.2) at the inner +# router domain "downlink". +# + +source ${genode_dir}/repos/dde_linux/run/wg_qemu_tap_preamble.inc + +create_boot_directory + +import_from_depot [depot_user]/src/[base_src] \ + [depot_user]/pkg/[drivers_nic_pkg] \ + [depot_user]/src/init \ + [depot_user]/src/nic_router \ + [depot_user]/src/libc \ + [depot_user]/src/libssh \ + [depot_user]/src/lighttpd \ + [depot_user]/src/openssl \ + [depot_user]/src/posix \ + [depot_user]/src/vfs \ + [depot_user]/src/vfs_lwip \ + [depot_user]/src/zlib + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2000-01-01 00:00 + 0123456789012345678901234567890123456789 + + + + + +# lighttpd configuration +server.port = 80 +server.document-root = "/website" +server.event-handler = "select" +server.network-backend = "write" +server.upload-dirs = ( "/tmp" ) +server.modules = ("mod_openssl") +index-file.names = ( + "index.xhtml", "index.html", "index.htm" +) +mimetype.assign = ( + ".html" => "text/html", + ".htm" => "text/html" +) +$SERVER["socket"] == ":443" { + ssl.engine = "enable" + ssl.pemfile = "/etc/lighttpd/example.pem" +} + + +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC4KHUZjDRew89c +wDlYPz9XFigcMDnDlHzdg2ByrGZIOUNYC5LH1QUK0TDbPP45Xx455niA0QY85dMQ +4DQx0Qk6+TDpVD3F2MYQgbIX6YkX9kgqX+jiHgsNzRD4KamNYmfUY+dJhlZEXWAF +uNSnRLvg4EH72AVKLLKiruGwkisW/AYU6dNE8iFOYL8Q75bBUADiQSDdD8vkpeXg +1NqxNyHPR6YRbA+vqcK0kbC8btKR9wG6m99OhTR4x3M87vtFFLNtJNEf54fYxi+L +1rljSqHbaXD+XJsVKgX+UlI1ZlYW4KqlMciMemkBp0CovCxLfsbMmkXAW2RONpkm ++sdO3CXFAgMBAAECggEAIKv00nqAVAuzP0ZPJivaZe3lYdLgfKVcXcRQGSgi4U9f +dkBfYxqU0W15mHvCspUAfM85s8jhrW4suwK739axJ4hMOCkc6Hvj78vCt+FT1C96 +cCIh4/PmjCVEjHJ/xTifKRwsTWwK5AgY4AsBl0dneabvremOTrGNY7VZDwVvpZz1 +qXkSNjQ63tZKj9cESO5ceGLzuBAG6JDDpqJM5fmdsQ36/QVz9Gogr8bXEWFM1TOo +lWVAPB/l6nqKurfMv+5th354+owv9CGKxqLBE1fujwE2VogBz7mkR/rnABOPU5ev +wQVLXoUkO2bI8Uvc28lChaiG6ihfdmNCmwoi56HFRQKBgQDj0WoIxiY7H42KV7Hh +uQZv/0aoQyjXuqJ7Vq0HdxOAxZr0GpSYgo3MTZWooI2AnAstPHXo0BsQr+XVijWm +xiDxMM4p9nrBzjEIHwyDaf62Pz/6lIPdenynLiEIOUbocJ3r0/3tCrY3U7fgjzYY +f9PZmXKEOOKdbVPyXG0OIJ/ADwKBgQDO8GkCdVGy/YB0X7ntqcBG0xgmDnKRmYpQ +X7Tb377AT2lzvftxaRVrx+UXtvFdy4xdrxjqHJCgOHT/fsAfjJlo7v1+KhTvE0pt +jCdJPLbzXJRwaISaeEaMJ/N8Vv/j2/YuoS5M5vh4NlWeO16HtF7N9V9cMEZ5iRW1 +9G/eWgOo6wKBgQCY6rn3xblnuhgxogd+ccmGZ50v2FST6WyiyV0/Q4hNyVXnP+g6 +LneriPBJzertRtChvpGOghGIs+jb2veESD1YZ+Aafp2LdTGoN98YXo9gGTiCpCmX +Al6lgOsfMAMOhnkaEKPC9ou0u3cTPk2bSEIVL1CUu/IwpW/RoIR7FR7ltQKBgQDA +RAmsqQfhPzqL5SzALclhhFuZcC7uLDOf/WvyJW37C000pjzp3/JxE2Y8pFKZDLc7 +i6WgTi3pTssVXtRt+5nFLtcC02Jjxg6OvXr6xphMf6XC0rjxM/KH4c6Npd9V+1Y9 +eK+l76rHNeRSgWKQvvqebO3On2O7I6yyQ4t0kTl5RQKBgQCbX1cTtNmNr6HNleXL +zfclKESSYy57uq3fQxhRrEE2ZNbemLOxEuoBCFYoMwpZEjC1GZyICrM7o5673/Ih +I0oZerUBmt2l8noZCQoITEa97bCbp2vIdHYnCf/H3Nf2qM329fc00kAmm7vUVRgM +4BqXnuFcAOuY68sgp9JArzK+EQ== +-----END PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDazCCAlOgAwIBAgIUYPOYXijLmMjjlgRCGHuZeyP0iPEwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCREUxEzARBgNVBAgMClNvbWUtU3RhdGUxDTALBgNVBAoM +BFRlc3QxEjAQBgNVBAMMCTEwLjAuMi41NTAeFw0yMDA1MTQxNDQ0MzlaFw00NzA5 +MzAxNDQ0MzlaMEUxCzAJBgNVBAYTAkRFMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0w +CwYDVQQKDARUZXN0MRIwEAYDVQQDDAkxMC4wLjIuNTUwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC4KHUZjDRew89cwDlYPz9XFigcMDnDlHzdg2ByrGZI +OUNYC5LH1QUK0TDbPP45Xx455niA0QY85dMQ4DQx0Qk6+TDpVD3F2MYQgbIX6YkX +9kgqX+jiHgsNzRD4KamNYmfUY+dJhlZEXWAFuNSnRLvg4EH72AVKLLKiruGwkisW +/AYU6dNE8iFOYL8Q75bBUADiQSDdD8vkpeXg1NqxNyHPR6YRbA+vqcK0kbC8btKR +9wG6m99OhTR4x3M87vtFFLNtJNEf54fYxi+L1rljSqHbaXD+XJsVKgX+UlI1ZlYW +4KqlMciMemkBp0CovCxLfsbMmkXAW2RONpkm+sdO3CXFAgMBAAGjUzBRMB0GA1Ud +DgQWBBQvSHuosL/SDn/8sKl0dpyPeFvOfjAfBgNVHSMEGDAWgBQvSHuosL/SDn/8 +sKl0dpyPeFvOfjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBR +sGYEuRwIU/tmAmTbniptItN9VE0NNj9QeKh+hKQ9cHvhxmlBlf5b7Vb2JaRZdy88 +kRIFKiNkyjgQVg+5KuEIcg17mHSal7zG+jIZ3c1bIpVCM4AjUe7EXl8LM4+dJ5sX +Bwpd34tUk2edOiT8R/dU7uesxCdeIQ2FfvKyrXca73nj+UTvFGXUk/9mWY8KAaYc +F/PWBhiZhJD4/dkUHJnrVtjpcqW2Io8bFmrMq2vfqQv+W2FZGCsHgXkAZO2E0jyQ +5eOrwzgWRtMc5PvoGvqQfefseaLs0fvSQdcPqfv88Eqk5NGTOCIW8/KEsBwFJuwa +EpA5DBBklj8UE2CdONvN +-----END CERTIFICATE----- + + + + + + + + Hello + + +

Hello Genode!

+ I am bold ;-) + + +
+
+ +
+ +
+ + + + + + + + + + +
+ +
+} + +build { app/wireguard } + +build_boot_image { wireguard } + +run_genode_until forever diff --git a/repos/dde_linux/run/wg_ping_inwards.run b/repos/dde_linux/run/wg_ping_inwards.run new file mode 100644 index 0000000000..71674f2185 --- /dev/null +++ b/repos/dde_linux/run/wg_ping_inwards.run @@ -0,0 +1,161 @@ +# +# Let the host Linux ping a Genode in Qemu through a Wireguard tunnel. +# + +source ${genode_dir}/repos/dde_linux/run/wg_qemu_tap_preamble.inc + +create_boot_directory + +import_from_depot [depot_user]/src/[base_src] \ + [depot_user]/pkg/[drivers_nic_pkg] \ + [depot_user]/src/init \ + [depot_user]/src/nic_router + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +build { app/wireguard } + +build_boot_image { wireguard } + +run_genode_until "uplink\] dynamic IP config: interface 10.0.2.3" 10 + +set timeout 60 + +append wait_for_string "64 bytes from 10.0.9.2.*" +append wait_for_string "64 bytes from 10.0.9.2.*" +append wait_for_string "64 bytes from 10.0.9.2.*\n" + +eval spawn ping 10.0.9.2 +expect { + -re $wait_for_string { } + eof { + puts stderr "Error: Spawned process died unexpectedly"; + exit -3 + } + timeout { + puts stderr "Error: Test execution timed out"; + exit -2 + } +} diff --git a/repos/dde_linux/run/wg_ping_outwards.run b/repos/dde_linux/run/wg_ping_outwards.run new file mode 100644 index 0000000000..adcc5f305c --- /dev/null +++ b/repos/dde_linux/run/wg_ping_outwards.run @@ -0,0 +1,172 @@ +# +# Let a Genode in Qemu ping the host Linux through a Wireguard tunnel. +# + +source ${genode_dir}/repos/dde_linux/run/wg_qemu_tap_preamble.inc + +create_boot_directory + +import_from_depot [depot_user]/src/[base_src] \ + [depot_user]/pkg/[drivers_nic_pkg] \ + [depot_user]/src/init \ + [depot_user]/src/nic_router + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + +build { app/wireguard app/ping } + +build_boot_image { wireguard ping } + +append wait_for_string "64 bytes from 10.0.9.1.*" +append wait_for_string "64 bytes from 10.0.9.1.*" +append wait_for_string "64 bytes from 10.0.9.1.*\n" + +run_genode_until $wait_for_string 60 diff --git a/repos/dde_linux/run/wg_qemu_tap_preamble.inc b/repos/dde_linux/run/wg_qemu_tap_preamble.inc new file mode 100644 index 0000000000..e1b6ef0344 --- /dev/null +++ b/repos/dde_linux/run/wg_qemu_tap_preamble.inc @@ -0,0 +1,110 @@ +# +# Preamble for WireGuard tests that run in Qemu and use a Qemu netdev TAP +# device to create a tunnel between the WireGuard device in the guest system +# and a Wireguard device in the host system. This script checks that the +# target platform is supported, installs the correct Qemu arguments, sets up +# the host WireGuard device, and ensures that the host WireGuard setup is +# undone whenever the test terminates. +# + +if {[expr ![have_spec arm_64] && ![have_spec x86_64]]} { + puts "Run script is not supported on this platform." + exit 0 +} + +if {[expr [have_spec arm_64] && ![have_board virt_qemu]]} { + puts "Run script is not supported on this platform." + exit 0 +} + +if {[expr ![have_include power_on/qemu]]} { + puts "Test requires Qemu." + exit 0 +} + +append wg_board_qemu_args " -m 512 " +append wg_board_qemu_args " -nographic " +append wg_board_qemu_args " -netdev tap,id=net0,ifname=tap0,script=no,downscript=no " +append wg_board_qemu_args " -smp 4 " + +if {[have_board virt_qemu]} { + + append wg_board_qemu_args " -global virtio-mmio.force-legacy=false " + append wg_board_qemu_args " -device virtio-net-device,bus=virtio-mmio-bus.0,netdev=net0 " + append wg_board_qemu_args " -M virt,virtualization=true,gic-version=3 " + append wg_board_qemu_args " -cpu cortex-a53 " + +} elseif {[have_spec x86_64]} { + + append wg_board_qemu_args " -machine q35 " + append wg_board_qemu_args " -net nic,model=e1000,netdev=net0 " + +} else { + + puts "Run script is not supported on this platform." + exit 0 +} + +proc board_qemu_args { } { + global wg_board_qemu_args + return $wg_board_qemu_args +} + +proc set_up_host_wg {} { + + puts "Set up host WireGuard" + + exec sudo rm -f udhcpd.conf udhcpd.leases + exec sudo ip tuntap del dev tap0 mode tap + + set fd [open udhcpd.conf w] + puts $fd "interface tap0" + puts $fd "start 10.0.2.3" + puts $fd "end 10.0.2.4" + puts $fd "max_leases 2" + puts $fd "lease_file udhcpd.leases" + puts $fd "pidfile udhcpd.pid" + puts $fd "option dns 10.0.2.1 10.0.2.2" + puts $fd "option subnet 255.255.255.0" + puts $fd "option router 10.0.2.1" + close $fd + + set fd [open udhcpd.leases w] + close $fd + + exec sudo ip tuntap add dev tap0 mode tap user $::tcl_platform(user) + exec sudo ip address flush dev tap0 + exec sudo ip address add 10.0.2.1/24 dev tap0 + exec sudo ip link set tap0 up + + exec sudo udhcpd udhcpd.conf + + exec echo "0CtU34qsl97IGiYKSO4tMaF/SJvy04zzeQkhZEbZSk0=" > wg_private_key + exec chmod 700 wg_private_key + exec sudo ip link add wg0 type wireguard + exec sudo ip addr add 10.0.9.1/24 dev wg0 + exec sudo wg set wg0 private-key wg_private_key listen-port 49001 + exec sudo ip link set wg0 up + exec sudo wg set wg0 peer "GrvyALPZ3PQ2AWM+ovxJqnxSqKpmTyqUui5jH+C8I0E=" allowed-ips 10.0.9.2/32 endpoint 10.0.2.3:49002 +} + +proc undo_host_wg_setup {} { + + puts "Undo host WireGuard setup" + exec sudo pkill -F udhcpd.pid + exec sudo ip link set wg0 down + exec sudo ip link delete dev wg0 + exec sudo ip link set tap0 down + exec sudo ip address flush dev tap0 + exec sudo ip link delete tap0 + exec sudo rm -rf wg_private_key udhcpd.conf udhcpd.leases udhcpd.pid +} + +rename exit run_tool_exit +proc exit {{status 0}} { + + undo_host_wg_setup + run_tool_exit $status +} + +set_up_host_wg diff --git a/repos/dde_linux/src/app/wireguard/README b/repos/dde_linux/src/app/wireguard/README new file mode 100644 index 0000000000..70833f9368 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/README @@ -0,0 +1,8 @@ + +:Warning: + +Although in principal functioning, the WireGuard port has not been exposed to a +sufficient amount of real-world testing, so far. Therefore, we strongly +recommend not to use it in any security-critical scenarios! There is no +guarantee that the port meets any of the security goals pursued by the +WireGuard protocol or other WireGuard implementations! diff --git a/repos/dde_linux/src/app/wireguard/arp_cache.cc b/repos/dde_linux/src/app/wireguard/arp_cache.cc new file mode 100644 index 0000000000..edafe9f94e --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/arp_cache.cc @@ -0,0 +1,99 @@ +/* +* \brief Cache for received ARP information +* \author Martin Stein +* \date 2016-08-19 +*/ + +/* +* Copyright (C) 2016-2017 Genode Labs GmbH +* +* This file is part of the Genode OS framework, which is distributed +* under the terms of the GNU Affero General Public License version 3. +*/ + +/* local includes */ +#include + +using namespace Net; +using namespace Genode; + + +/********************* + ** Arp_cache_entry ** + *********************/ + +Arp_cache_entry::Arp_cache_entry(Ipv4_address const &ip, + Mac_address const &mac) +: + _ip(ip), _mac(mac) +{ } + + +bool Arp_cache_entry::_higher(Ipv4_address const &ip) const +{ + return memcmp(ip.addr, _ip.addr, sizeof(_ip.addr)) > 0; +} + + +Arp_cache_result Arp_cache_entry::find_by_ip(Ipv4_address const &ip) const +{ + if (ip == _ip) { + return Const_pointer { *this }; + } + Arp_cache_entry const *const entry = child(_higher(ip)); + if (!entry) { + return Arp_cache_result(Arp_cache_error::NO_MATCH); + } + return entry->find_by_ip(ip); +} + +void Arp_cache_entry::print(Output &output) const +{ + Genode::print(output, _ip, " > ", _mac); +} + + +/*************** + ** Arp_cache ** + ***************/ + +void Arp_cache::new_entry(Ipv4_address const &ip, Mac_address const &mac) +{ + if (_entries[_curr].constructed()) { + remove(&(*_entries[_curr])); + } + _entries[_curr].construct(ip, mac); + Arp_cache_entry &entry = *_entries[_curr]; + insert(&entry); + if (_curr < NR_OF_ENTRIES - 1) { + _curr++; + } else { + _curr = 0; + }; +} + + +Arp_cache_result Arp_cache::find_by_ip(Ipv4_address const &ip) const +{ + if (!first()) { + return Arp_cache_error::NO_MATCH; + } + return first()->find_by_ip(ip); +} + + +void Arp_cache::destroy_entries_with_mac(Mac_address const &mac) +{ + for (unsigned curr = 0; curr < NR_OF_ENTRIES; curr++) { + try { + Arp_cache_entry &entry = *_entries[curr]; + if (entry.mac() != mac) { + continue; + } + log("destroy ARP entry ", entry); + remove(&entry); + _entries[curr].destruct(); + + } catch (Arp_cache_entry_slot::Deref_unconstructed_object) { } + } +} diff --git a/repos/dde_linux/src/app/wireguard/arp_cache.h b/repos/dde_linux/src/app/wireguard/arp_cache.h new file mode 100644 index 0000000000..e97d722063 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/arp_cache.h @@ -0,0 +1,98 @@ +/* +* \brief Cache for received ARP information +* \author Martin Stein +* \date 2016-08-19 +*/ + +/* +* Copyright (C) 2016-2017 Genode Labs GmbH +* +* This file is part of the Genode OS framework, which is distributed +* under the terms of the GNU Affero General Public License version 3. +*/ + +#ifndef _ARP_CACHE_H_ +#define _ARP_CACHE_H_ + +/* Genode includes */ +#include +#include +#include +#include +#include + +/* dde_linux wireguard includes */ +#include + +namespace Net { + + enum class Arp_cache_error { NO_MATCH }; + class Domain; + class Arp_cache; + class Arp_cache_entry; + using Arp_cache_entry_slot = Genode::Constructible; + using Arp_cache_result = Genode::Attempt, Arp_cache_error>; +} + + +class Net::Arp_cache_entry : public Genode::Avl_node +{ + private: + + Ipv4_address const _ip; + Mac_address const _mac; + + bool _higher(Ipv4_address const &ip) const; + + public: + + Arp_cache_entry(Ipv4_address const &ip, Mac_address const &mac); + + Arp_cache_result find_by_ip(Ipv4_address const &ip) const; + + + /************** + ** Avl_node ** + **************/ + + bool higher(Arp_cache_entry *entry) { return _higher(entry->_ip); } + + + /*************** + ** Accessors ** + ***************/ + + Mac_address const &mac() const { return _mac; } + Ipv4_address const &ip() const { return _ip; } + + + /********* + ** log ** + *********/ + + void print(Genode::Output &output) const; +}; + + +class Net::Arp_cache : public Genode::Avl_tree +{ + private: + + enum { + ENTRIES_SIZE = 1024 * sizeof(Genode::addr_t), + NR_OF_ENTRIES = ENTRIES_SIZE / sizeof(Arp_cache_entry), + }; + + Arp_cache_entry_slot _entries[NR_OF_ENTRIES]; + unsigned _curr = 0; + + public: + + void new_entry(Ipv4_address const &ip, Mac_address const &mac); + + void destroy_entries_with_mac(Mac_address const &mac); + + Arp_cache_result find_by_ip(Ipv4_address const &ip) const; +}; + +#endif /* _ARP_CACHE_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/arp_waiter.cc b/repos/dde_linux/src/app/wireguard/arp_waiter.cc new file mode 100644 index 0000000000..1f89326c20 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/arp_waiter.cc @@ -0,0 +1,40 @@ +/* + * \brief Aspect of waiting for an ARP reply + * \author Martin Stein + * \date 2016-08-19 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* local includes */ +#include + +using namespace Net; +using namespace Genode; + + +Arp_waiter::Arp_waiter(Arp_waiter_list &list, + Ipv4_address const &ip, + Packet_descriptor const &packet) +: + _list(list), _le(this), _ip(ip), _packet(packet) +{ + _list.insert(&_le); +} + + +Arp_waiter::~Arp_waiter() +{ + _list.remove(&_le); +} + + +void Arp_waiter::print(Output &output) const +{ + Genode::print(output, "IP ", _ip); +} diff --git a/repos/dde_linux/src/app/wireguard/arp_waiter.h b/repos/dde_linux/src/app/wireguard/arp_waiter.h new file mode 100644 index 0000000000..2645e065d4 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/arp_waiter.h @@ -0,0 +1,66 @@ +/* + * \brief Remember packets that wait for ARP replies at different interfaces + * \author Martin Stein + * \date 2016-08-19 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _ARP_WAITER_H_ +#define _ARP_WAITER_H_ + +/* local includes */ +#include + +/* Genode includes */ +#include +#include + +namespace Net { + + using Packet_descriptor = ::Nic::Packet_descriptor; + class Arp_waiter; + using Arp_waiter_list_element = Genode::List_element; + using Arp_waiter_list = Net::List; +} + + +class Net::Arp_waiter +{ + private: + + Arp_waiter_list &_list; + Arp_waiter_list_element _le; + Ipv4_address const _ip; + Packet_descriptor const _packet; + + public: + + Arp_waiter(Arp_waiter_list &list, + Ipv4_address const &ip, + Packet_descriptor const &packet); + + ~Arp_waiter(); + + + /********* + ** Log ** + *********/ + + void print(Genode::Output &output) const; + + + /*************** + ** Accessors ** + ***************/ + + Ipv4_address const &ip() const { return _ip; } + Packet_descriptor const &packet() const { return _packet; } +}; + +#endif /* _ARP_WAITER_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/base64.cc b/repos/dde_linux/src/app/wireguard/base64.cc new file mode 100644 index 0000000000..9078f5d5ea --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/base64.cc @@ -0,0 +1,59 @@ +/*************************************************** + ** FIXME ** + ** Slightly adapted copy from wireguard-tools. ** + ** Replace with contrib or Genode implementation ** + ***************************************************/ + +/* base includes */ +#include + +/* app/wireguard includes */ +#include + +using namespace Genode; + + +int decode_base64(const char src[4]) +{ + int val = 0; + + for (unsigned int i = 0; i < 4; ++i) + val |= (-1 + + ((((('A' - 1) - src[i]) & (src[i] - ('Z' + 1))) >> 8) & (src[i] - 64)) + + ((((('a' - 1) - src[i]) & (src[i] - ('z' + 1))) >> 8) & (src[i] - 70)) + + ((((('0' - 1) - src[i]) & (src[i] - ('9' + 1))) >> 8) & (src[i] + 5)) + + ((((('+' - 1) - src[i]) & (src[i] - ('+' + 1))) >> 8) & 63) + + ((((('/' - 1) - src[i]) & (src[i] - ('/' + 1))) >> 8) & 64) + ) << (18 - 6 * i); + return val; +} + + +bool key_from_base64(uint8_t key[WG_KEY_LEN], const char *base64) +{ + unsigned int i; + volatile uint8_t ret = 0; + int val; + char tmp[4]; + + if (strlen(base64) != WG_KEY_LEN_BASE64 - 1 || base64[WG_KEY_LEN_BASE64 - 2] != '=') + return false; + + for (i = 0; i < WG_KEY_LEN / 3; ++i) { + val = decode_base64(&base64[i * 4]); + ret |= (uint8_t)((uint32_t)val >> 31); + key[i * 3 + 0] = (uint8_t)((val >> 16) & 0xff); + key[i * 3 + 1] = (uint8_t)((val >> 8) & 0xff); + key[i * 3 + 2] = (uint8_t)(val & 0xff); + } + tmp[0] = base64[i * 4 + 0]; + tmp[1] = base64[i * 4 + 1]; + tmp[2] = base64[i * 4 + 2]; + tmp[3] = 'A'; + val = decode_base64(tmp); + ret |= (uint8_t)(((uint32_t)val >> 31) | (val & 0xff)); + key[i * 3 + 0] = (uint8_t)((val >> 16) & 0xff); + key[i * 3 + 1] = (uint8_t)((val >> 8) & 0xff); + + return 1 & ((ret - 1) >> 8); +} diff --git a/repos/dde_linux/src/app/wireguard/base64.h b/repos/dde_linux/src/app/wireguard/base64.h new file mode 100644 index 0000000000..bc3e1a2380 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/base64.h @@ -0,0 +1,22 @@ +/*************************************************** + ** FIXME ** + ** Slightly adapted copy from wireguard-tools. ** + ** Replace with contrib or Genode implementation ** + ***************************************************/ + +#ifndef _BASE64_H_ +#define _BASE64_H_ + +/* base includes */ +#include + +enum { + WG_KEY_LEN = 32, + WG_KEY_LEN_BASE64 = ((((WG_KEY_LEN) + 2) / 3) * 4 + 1), +}; + +int decode_base64(const char src[4]); + +bool key_from_base64(Genode::uint8_t key[WG_KEY_LEN], const char *base64); + +#endif /* _BASE64_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/config_model.cc b/repos/dde_linux/src/app/wireguard/config_model.cc new file mode 100644 index 0000000000..9a1a42f74f --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/config_model.cc @@ -0,0 +1,161 @@ +/* + * \brief A differentially updating model of the component configuration + * \author Stefan Kalkowski + * \author Martin Stein + * \date 2022-01-07 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* dde_linux wireguard includes */ +#include + +using namespace Genode; +using namespace Net; +using namespace Wireguard; + + +/****************** + ** Config_model ** + ******************/ + +Config_model::Config_model(Genode::Allocator &alloc) +: + _alloc { alloc } +{ } + + +void Config_model::update(genode_wg_config_callbacks &callbacks, + Xml_node node) +{ + if (!_config.constructed()) { + + _config.construct( + node.attribute_value("private_key", Key_base64 { }), + node.attribute_value("listen_port", (uint16_t)0U), + node.attribute_value("interface", Ipv4_address_prefix { })); + + uint8_t private_key[WG_KEY_LEN]; + if (!_config->private_key_b64().valid() || + !key_from_base64(private_key, _config->private_key_b64().string())) { + + error("Invalid private key!"); + } + callbacks.add_device(_config->listen_port(), private_key); + } + Peer_update_policy policy { _alloc, callbacks, _config->listen_port() }; + _peers.update_from_xml(policy, node); +} + + +/************************** + ** Config_model::Config ** + **************************/ + +Config_model::Config::Config(Key_base64 private_key_b64, + uint16_t listen_port, + Ipv4_address_prefix interface) +: + _private_key_b64 { private_key_b64 }, + _listen_port { listen_port }, + _interface { interface } +{ } + + +/************************************** + ** Config_model::Peer_update_policy ** + **************************************/ + +void Config_model::Peer_update_policy::update_element(Element &, + Xml_node ) +{ } + + +Config_model:: +Peer_update_policy::Peer_update_policy(Allocator &alloc, + genode_wg_config_callbacks &callbacks, + uint16_t listen_port) +: + _alloc { alloc }, + _callbacks { callbacks }, + _listen_port { listen_port } +{ } + + +void Config_model::Peer_update_policy::destroy_element(Element &peer) +{ + _callbacks.remove_peer( + _listen_port, peer._endpoint_ip.addr, peer._endpoint_port); + + destroy(_alloc, &peer); +} + + +Config_model::Peer_update_policy::Element & +Config_model::Peer_update_policy::create_element(Xml_node node) +{ + Ipv4_address endpoint_ip { node.attribute_value("endpoint_ip", Ipv4_address { }) }; + uint16_t endpoint_port { node.attribute_value("endpoint_port", (uint16_t)0U ) }; + Key_base64 public_key_b64 { node.attribute_value("public_key", Key_base64 { }) }; + Ipv4_address_prefix allowed_ip { node.attribute_value("allowed_ip", Ipv4_address_prefix { }) }; + + uint8_t public_key[WG_KEY_LEN]; + if (!public_key_b64.valid() || + !key_from_base64(public_key, public_key_b64.string())) { + + error("Invalid public key!"); + } + if (!allowed_ip.valid()) { + error("Invalid allowed ip!"); + } + _callbacks.add_peer( + _listen_port, endpoint_ip.addr, endpoint_port, public_key, + allowed_ip.address.addr, allowed_ip.prefix); + + return *( + new (_alloc) + Element(public_key_b64, endpoint_ip, endpoint_port, allowed_ip)); +} + + +bool +Config_model:: +Peer_update_policy::element_matches_xml_node(Element const &peer, + Xml_node node) +{ + Ipv4_address endpoint_ip { node.attribute_value("endpoint_ip", Ipv4_address { }) }; + uint16_t endpoint_port { node.attribute_value("endpoint_port", (uint16_t)0U ) }; + Key_base64 public_key_b64 { node.attribute_value("public_key", Key_base64 { }) }; + + return + (endpoint_ip == peer._endpoint_ip) && + (endpoint_port == peer._endpoint_port) && + (public_key_b64 == peer._public_key_b64); +} + + +bool Config_model::Peer_update_policy::node_is_element(Xml_node node) +{ + return node.has_type("peer"); +} + + +/************************ + ** Config_model::Peer ** + ************************/ + +Config_model::Peer::Peer(Key_base64 public_key_b64, + Ipv4_address endpoint_ip, + uint16_t endpoint_port, + Ipv4_address_prefix allowed_ip) +: + _public_key_b64 { public_key_b64 }, + _endpoint_ip { endpoint_ip }, + _endpoint_port { endpoint_port }, + _allowed_ip { allowed_ip } +{ } diff --git a/repos/dde_linux/src/app/wireguard/config_model.h b/repos/dde_linux/src/app/wireguard/config_model.h new file mode 100644 index 0000000000..7467b61927 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/config_model.h @@ -0,0 +1,125 @@ +/* + * \brief A differentially updating model of the component configuration + * \author Stefan Kalkowski + * \author Martin Stein + * \date 2022-01-07 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _CONFIG_MODEL_H_ +#define _CONFIG_MODEL_H_ + +/* base includes */ +#include +#include +#include + +/* app/wireguard includes */ +#include +#include +#include + +namespace Wireguard { + + class Config_model; +} + + +class Wireguard::Config_model +{ + private: + + using Key_base64 = Genode::String; + + class Peer; + class Peer_update_policy; + + class Config + { + private: + + Key_base64 const _private_key_b64; + Genode::uint16_t const _listen_port; + Net::Ipv4_address_prefix const _interface; + + public: + + Config(Key_base64 private_key_b64, + Genode::uint16_t listen_port, + Net::Ipv4_address_prefix interface); + + + Key_base64 const &private_key_b64() const { return _private_key_b64; } + Genode::uint16_t listen_port() const { return _listen_port; } + Net::Ipv4_address_prefix const &interface() const { return _interface; } + }; + + Genode::Allocator &_alloc; + Genode::Constructible _config { }; + Genode::List_model _peers { }; + + public: + + Config_model(Genode::Allocator &alloc); + + void update(genode_wg_config_callbacks &callbacks, + Genode::Xml_node config_node); +}; + + +class Wireguard::Config_model::Peer : public Genode::List_model::Element +{ + friend class Peer_update_policy; + + private: + + Key_base64 _public_key_b64; + Net::Ipv4_address _endpoint_ip; + Genode::uint16_t _endpoint_port; + Net::Ipv4_address_prefix _allowed_ip; + + public: + + Peer(Key_base64 public_key_b64, + Net::Ipv4_address endpoint_ip, + Genode::uint16_t endpoint_port, + Net::Ipv4_address_prefix allowed_ip); +}; + + +class Wireguard::Config_model::Peer_update_policy +: + public Genode::List_model::Update_policy +{ + private: + + Genode::Allocator &_alloc; + genode_wg_config_callbacks &_callbacks; + Genode::uint16_t _listen_port; + + public: + + Peer_update_policy(Genode::Allocator &alloc, + genode_wg_config_callbacks &callbacks, + Genode::uint16_t listen_port); + + void destroy_element(Element &peer); + + Element & create_element(Genode::Xml_node node); + + void update_element(Element &peer, + Genode::Xml_node node); + + static bool element_matches_xml_node(Element const &peer, + Genode::Xml_node node); + + static bool node_is_element(Genode::Xml_node node); +}; + +#endif /* _CONFIG_MODEL_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/dhcp.h b/repos/dde_linux/src/app/wireguard/dhcp.h new file mode 100644 index 0000000000..19cb0f881b --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/dhcp.h @@ -0,0 +1,30 @@ +/* + * \brief DHCP related local utilities + * \author Martin Stein + * \date 2021-02-10 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _DHCP_H_ +#define _DHCP_H_ + +/* os includes */ +#include + +namespace Net { + + template + static Ipv4_address dhcp_ipv4_option(Dhcp_packet &dhcp) + { + try { return dhcp.option().value(); } + catch (Dhcp_packet::Option_not_found) { return Ipv4_address { }; } + } +} + +#endif /* _DHCP_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/dhcp_client.cc b/repos/dde_linux/src/app/wireguard/dhcp_client.cc new file mode 100644 index 0000000000..27191bed94 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/dhcp_client.cc @@ -0,0 +1,285 @@ +/* + * \brief DHCP client state model + * \author Martin Stein + * \date 2016-08-24 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* dde_linux wireguard includes */ +#include +#include + +enum { PKT_SIZE = 1024 }; + +using namespace Genode; +using namespace Net; +using namespace Wireguard; + +using Message_type = Dhcp_packet::Message_type; +using Dhcp_options = Dhcp_packet::Options_aggregator; + + +/*************** + ** Utilities ** + ***************/ + +void append_param_req_list(Dhcp_options &dhcp_opts) +{ + dhcp_opts.append_param_req_list([&] (Dhcp_options::Parameter_request_list_data &data) { + data.append_param_req(); + data.append_param_req(); + data.append_param_req(); + data.append_param_req(); + data.append_param_req(); + data.append_param_req(); + data.append_param_req(); + }); +} + + +/***************** + ** Dhcp_client ** + *****************/ + +Dhcp_client::Dhcp_client(Timer::Connection &timer, + Nic_connection &nic_connection) +: + _nic_connection { nic_connection }, + _timeout { timer, *this, &Dhcp_client::_handle_timeout } +{ } + + +void Dhcp_client::discover() +{ + _set_state(State::SELECT, _nic_connection.dhcp_discover_timeout()); + _send(Message_type::DISCOVER, Ipv4_address(), Ipv4_address(), + Ipv4_address()); +} + + +void Dhcp_client::_rerequest(State next_state) +{ + _set_state(next_state, _rerequest_timeout(2)); + Ipv4_address const client_ip { + _nic_connection.ip_config().interface().address }; + + _send(Message_type::REQUEST, client_ip, Ipv4_address(), client_ip); +} + + +void Dhcp_client::_set_state(State state, Microseconds timeout) +{ + _state = state; + _timeout.schedule(timeout); +} + + +Microseconds Dhcp_client::_rerequest_timeout(unsigned lease_time_div_log2) +{ + /* FIXME limit the time because of shortcomings in timeout framework */ + enum { MAX_TIMEOUT_SEC = 3600 }; + uint64_t timeout_sec = _lease_time_sec >> lease_time_div_log2; + + if (timeout_sec > MAX_TIMEOUT_SEC) { + timeout_sec = MAX_TIMEOUT_SEC; + if (_nic_connection.verbose()) { + log("DHCP client: prune re-request timeout"); + } + } + return Microseconds(timeout_sec * 1000 * 1000); +} + + +void Dhcp_client::_handle_timeout(Duration) +{ + switch (_state) { + case State::BOUND: + + _rerequest(State::RENEW); + break; + + case State::RENEW: + + _rerequest(State::REBIND); + break; + + case State::REBIND: + + _nic_connection.discard_ip_config(); + discover(); + break; + + default: + + discover(); + break; + } +} + + +void Dhcp_client::handle_eth(Ethernet_frame ð, + Size_guard &size_guard) +{ + if (eth.dst() != _nic_connection.mac_address() && + eth.dst() != Mac_address(0xff)) + { + log("DHCP client: drop packet - ETH.DST does not target me"); + return; + } + if (eth.type() != Ethernet_frame::Type::IPV4) { + log("DHCP client: drop packet - ETH.TYPE is not IPV4"); + return; + } + Ipv4_packet &ip { eth.data(size_guard) }; + if (ip.protocol() != Ipv4_packet::Protocol::UDP) { + log("DHCP client: drop packet - IPV4.PROTOCOL is not UDP"); + return; + } + Udp_packet &udp { ip.data(size_guard) }; + if (!Dhcp_packet::is_dhcp(&udp)) { + log("DHCP client: drop packet - UDP does not carry DHCP"); + return; + } + Dhcp_packet &dhcp = udp.data(size_guard); + if (dhcp.op() != Dhcp_packet::REPLY) { + log("DHCP client: drop packet - DHCP.OP is not REPLY"); + return; + } + if (dhcp.client_mac() != _nic_connection.mac_address()) { + log("DHCP client: drop packet - DHCP.CLIENT_MAC is not my MAC address"); + return; + } + try { + Message_type const msg_type = + dhcp.option().value(); + + switch (_state) { + case State::SELECT: + + if (msg_type != Message_type::OFFER) { + log("DHCP client: drop packet - DHCP.MSG_TYPE is not OFFER"); + return; + } + _set_state(State::REQUEST, _nic_connection.dhcp_request_timeout()); + _send(Message_type::REQUEST, Ipv4_address(), + dhcp.option().value(), + dhcp.yiaddr()); + + break; + + case State::REQUEST: + { + if (msg_type != Message_type::ACK) { + log("DHCP client: drop packet - DHCP.MSG_TYPE is not ACK (state REQUEST)"); + return; + } + _lease_time_sec = dhcp.option().value(); + _set_state(State::BOUND, _rerequest_timeout(1)); + _nic_connection.ip_config_from_dhcp_ack(dhcp); + break; + } + case State::RENEW: + case State::REBIND: + + if (msg_type != Message_type::ACK) { + log("DHCP client: drop packet - DHCP.MSG_TYPE is not ACK (state RENEW/REBIND)"); + return; + } + _set_state(State::BOUND, _rerequest_timeout(1)); + _lease_time_sec = dhcp.option().value(); + break; + + default: + + log("DHCP client: drop packet - client doesn't expect reply"); + return; + } + } + catch (Dhcp_packet::Option_not_found) { + + log("DHCP client: drop packet - DHCP.MSG_TYPE missing"); + return; + } +} + + +void Dhcp_client::_send(Message_type msg_type, + Ipv4_address client_ip, + Ipv4_address server_ip, + Ipv4_address requested_ip) +{ + Mac_address client_mac = _nic_connection.mac_address(); + _nic_connection.send(PKT_SIZE, [&] (void *pkt_base, Size_guard &size_guard) { + + /* create ETH header of the request */ + Ethernet_frame ð = Ethernet_frame::construct_at(pkt_base, size_guard); + eth.dst(Mac_address(0xff)); + eth.src(client_mac); + eth.type(Ethernet_frame::Type::IPV4); + + /* create IP header of the request */ + enum { IPV4_TIME_TO_LIVE = 64 }; + size_t const ip_off = size_guard.head_size(); + Ipv4_packet &ip = eth.construct_at_data(size_guard); + ip.header_length(sizeof(Ipv4_packet) / 4); + ip.version(4); + ip.time_to_live(IPV4_TIME_TO_LIVE); + ip.protocol(Ipv4_packet::Protocol::UDP); + ip.src(client_ip); + ip.dst(Ipv4_address(0xff)); + + /* create UDP header of the request */ + size_t const udp_off = size_guard.head_size(); + Udp_packet &udp = ip.construct_at_data(size_guard); + udp.src_port(Port(Dhcp_packet::BOOTPC)); + udp.dst_port(Port(Dhcp_packet::BOOTPS)); + + /* create mandatory DHCP fields of the request */ + size_t const dhcp_off = size_guard.head_size(); + Dhcp_packet &dhcp = udp.construct_at_data(size_guard); + dhcp.op(Dhcp_packet::REQUEST); + dhcp.htype(Dhcp_packet::Htype::ETH); + dhcp.hlen(sizeof(Mac_address)); + dhcp.ciaddr(client_ip); + dhcp.client_mac(client_mac); + dhcp.default_magic_cookie(); + + /* append DHCP option fields to the request */ + Dhcp_options dhcp_opts(dhcp, size_guard); + dhcp_opts.append_option(msg_type); + switch (msg_type) { + case Message_type::DISCOVER: + append_param_req_list(dhcp_opts); + dhcp_opts.append_option(client_mac); + dhcp_opts.append_option((uint16_t)(PKT_SIZE - dhcp_off)); + break; + + case Message_type::REQUEST: + append_param_req_list(dhcp_opts); + dhcp_opts.append_option(client_mac); + dhcp_opts.append_option((uint16_t)(PKT_SIZE - dhcp_off)); + if (_state == State::REQUEST) { + dhcp_opts.append_option(requested_ip); + dhcp_opts.append_option(server_ip); + } + break; + + default: + class Bad_dhcp_message_type { }; + throw Bad_dhcp_message_type { }; + } + dhcp_opts.append_option(); + + /* fill in header values that need the packet to be complete already */ + udp.length((uint16_t)(size_guard.head_size() - udp_off)); + udp.update_checksum(ip.src(), ip.dst()); + ip.total_length(size_guard.head_size() - ip_off); + ip.update_checksum(); + }); +} diff --git a/repos/dde_linux/src/app/wireguard/dhcp_client.h b/repos/dde_linux/src/app/wireguard/dhcp_client.h new file mode 100644 index 0000000000..2f9ff8727a --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/dhcp_client.h @@ -0,0 +1,72 @@ +/* + * \brief DHCP client state model + * \author Martin Stein + * \date 2016-08-24 + */ + +/* + * Copyright (C) 2016-2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _DHCP_CLIENT_H_ +#define _DHCP_CLIENT_H_ + +/* base includes */ +#include + +/* dde_linux wireguard includes */ +#include + +namespace Wireguard { + + class Nic_connection; +} + +namespace Net { + + class Ethernet_frame; + class Dhcp_client; +} + +class Net::Dhcp_client +{ + private: + + enum class State + { + INIT = 0, SELECT = 1, REQUEST = 2, BOUND = 3, RENEW = 4, REBIND = 5 + }; + + Wireguard::Nic_connection &_nic_connection; + State _state { State::INIT }; + Timer::One_shot_timeout _timeout; + Genode::uint64_t _lease_time_sec = 0; + + void _handle_timeout(Genode::Duration); + + void _rerequest(State next_state); + + Genode::Microseconds _rerequest_timeout(unsigned lease_time_div_log2); + + void _set_state(State state, Genode::Microseconds timeout); + + void _send(Dhcp_packet::Message_type msg_type, + Ipv4_address client_ip, + Ipv4_address server_ip, + Ipv4_address requested_ip); + + public: + + Dhcp_client(Timer::Connection &timer, + Wireguard::Nic_connection &nic_connection); + + void handle_eth(Ethernet_frame ð, + Size_guard &size_guard); + + void discover(); +}; + +#endif /* _DHCP_CLIENT_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/dummies.c b/repos/dde_linux/src/app/wireguard/dummies.c new file mode 100644 index 0000000000..00c74a70d4 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/dummies.c @@ -0,0 +1,269 @@ +/** + * \brief Dummy definitions of Linux Kernel functions + * \author Stefan Kalkowski + * \author Martin Stein + * \date 2022-01-07 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include + + +#include + +int __cpuhp_setup_state(enum cpuhp_state state,const char * name,bool invoke,int (* startup)(unsigned int cpu),int (* teardown)(unsigned int cpu),bool multi_instance) +{ + lx_emul_trace(__func__); + return 0; +} + + +#include +struct pt_regs * __irq_regs = NULL; + + +#include + +int __preempt_count = 0; + + +#include + +void account_process_tick(struct task_struct * p,int user_tick) +{ + lx_emul_trace(__func__); +} + + +#include + +int add_random_ready_callback(struct random_ready_callback * rdy) +{ + lx_emul_trace(__func__); + return 0; +} + + +extern int __init buses_init(void); +int __init buses_init(void) +{ + lx_emul_trace(__func__); + return 0; +} + + +#include + +void calc_global_load(void) +{ + lx_emul_trace(__func__); +} + + +extern int __init classes_init(void); +int __init classes_init(void) +{ + lx_emul_trace(__func__); + return 0; +} + + +extern int __init devices_init(void); +int __init devices_init(void) +{ + lx_emul_trace(__func__); + return 0; +} + + +#include + +int __init early_irq_init(void) +{ + lx_emul_trace(__func__); + return 0; +} + + +#include +#include + +int generic_handle_irq(unsigned int irq) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const struct trace_print_flags gfpflag_names[] = { {0,NULL}}; + + +#include + +void ignore_signals(struct task_struct * t) +{ + lx_emul_trace(__func__); +} + + +#include + +const struct ipv6_stub *ipv6_stub = NULL; + + +#include + +unsigned long net_rand_noise; + + +#include + +const struct trace_print_flags pageflag_names[] = { {0,NULL}}; + + +extern int __init platform_bus_init(void); +int __init platform_bus_init(void) +{ + lx_emul_trace(__func__); + return 0; +} + + +#include +#include +#include + +void rcu_barrier(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void rcu_sched_clock_irq(int user) +{ + lx_emul_trace(__func__); +} + + +#include + +int register_netdevice(struct net_device * dev) +{ + lx_emul_trace(__func__); + return 0; +} + + +#include + +int register_pernet_device(struct pernet_operations * ops) +{ + lx_emul_trace(__func__); + return 0; +} + + +#include + +void register_syscore_ops(struct syscore_ops * ops) +{ + lx_emul_trace(__func__); +} + + +#include + +void sk_set_memalloc(struct sock * sk) +{ + lx_emul_trace(__func__); +} + + +#include + +void synchronize_net(void) +{ + lx_emul_trace(__func__); +} + + +#include + +void update_vsyscall(struct timekeeper * tk) +{ + lx_emul_trace(__func__); +} + + +#include + +const struct trace_print_flags vmaflag_names[] = { {0,NULL}}; + + +#include + +void rtnl_lock(void) +{ + lx_emul_trace(__func__); +} + + +#include + +void rtnl_unlock(void) +{ + lx_emul_trace(__func__); +} + + +#include + +void do_trace_netlink_extack(const char * msg) +{ + lx_emul_trace(__func__); +} + + +#include + +void napi_enable(struct napi_struct * n) +{ + lx_emul_trace(__func__); +} + + +#include + +struct mem_section ** mem_section = NULL; + + +unsigned long phys_base = 0; + + +#include + +DEFINE_STATIC_KEY_FALSE(bpf_stats_enabled_key); + + +#include + +int net_ratelimit(void) +{ + lx_emul_trace(__func__); + return 0; +} + + +__wsum csum_partial(const void * buff,int len,__wsum sum) +{ + lx_emul_trace_and_stop(__func__); +} diff --git a/repos/dde_linux/src/app/wireguard/genode_c_api/wireguard.c b/repos/dde_linux/src/app/wireguard/genode_c_api/wireguard.c new file mode 100644 index 0000000000..538250259b --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/genode_c_api/wireguard.c @@ -0,0 +1,468 @@ +/* + * \brief Glue code between Genode C++ code and Wireguard C code + * \author Martin Stein + * \date 2022-01-07 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* app/wireguard includes */ +#include +#include + +/* contrib linux includes */ +#include <../drivers/net/wireguard/device.h> +#include <../drivers/net/wireguard/messages.h> +#include +#include +#include + + +/* + * The contrib code expects the private device data to be located directly + + behind the public data with a certain alignment. It does pointer arithmetic + * based on a pointer to the public data in order to determine the private + * data's base. + */ +struct genode_wg_net_device +{ + struct net_device public_data; + struct wg_device private_data __attribute__((aligned(NETDEV_ALIGN))); + int pcpu_refcnt; +} +__attribute__((aligned(NETDEV_ALIGN), packed)); + + +struct genode_wg_nlattr_ifname +{ + struct nlattr header; + genode_wg_u8_t data[1] __attribute__((aligned(NLA_ALIGNTO))); +} +__attribute__((aligned(NLA_ALIGNTO), packed)); + + +struct genode_wg_nlattr_private_key +{ + struct nlattr header; + genode_wg_u8_t data[NOISE_PUBLIC_KEY_LEN] __attribute__((aligned(NLA_ALIGNTO))); +} +__attribute__((aligned(NLA_ALIGNTO), packed)); + + +struct genode_wg_nlattr_public_key +{ + struct nlattr header; + genode_wg_u8_t data[NOISE_PUBLIC_KEY_LEN] __attribute__((aligned(NLA_ALIGNTO))); +} +__attribute__((aligned(NLA_ALIGNTO), packed)); + + +struct genode_wg_nlattr_u8 +{ + struct nlattr header; + genode_wg_u8_t data __attribute__((aligned(NLA_ALIGNTO))); +} +__attribute__((aligned(NLA_ALIGNTO), packed)); + + +struct genode_wg_nlattr_u16 +{ + struct nlattr header; + genode_wg_u16_t data __attribute__((aligned(NLA_ALIGNTO))); +} +__attribute__((aligned(NLA_ALIGNTO), packed)); + + +struct genode_wg_nlattr_u32 +{ + struct nlattr header; + genode_wg_u32_t data __attribute__((aligned(NLA_ALIGNTO))); +} +__attribute__((aligned(NLA_ALIGNTO), packed)); + + +struct genode_wg_nlattr_in_addr +{ + struct nlattr header; + struct in_addr data __attribute__((aligned(NLA_ALIGNTO))); +} +__attribute__((aligned(NLA_ALIGNTO), packed)); + + +struct genode_wg_nlattr_sockaddr +{ + struct nlattr header; + struct sockaddr data __attribute__((aligned(NLA_ALIGNTO))); +} +__attribute__((aligned(NLA_ALIGNTO), packed)); + + +struct genode_wg_nlattr_allowedip +{ + struct nlattr header; + struct genode_wg_nlattr_u16 family __attribute__((aligned(NLA_ALIGNTO))); + struct genode_wg_nlattr_in_addr ipaddr __attribute__((aligned(NLA_ALIGNTO))); + struct genode_wg_nlattr_u8 cidr_mask __attribute__((aligned(NLA_ALIGNTO))); +} +__attribute__((aligned(NLA_ALIGNTO), packed)); + + +struct genode_wg_nlattr_allowedips +{ + struct nlattr header; + struct genode_wg_nlattr_allowedip ip_0 __attribute__((aligned(NLA_ALIGNTO))); +} +__attribute__((aligned(NLA_ALIGNTO), packed)); + + +struct genode_wg_nlattr_peer +{ + struct nlattr header; + struct genode_wg_nlattr_public_key public_key __attribute__((aligned(NLA_ALIGNTO))); + struct genode_wg_nlattr_sockaddr endpoint __attribute__((aligned(NLA_ALIGNTO))); + struct genode_wg_nlattr_u32 flags __attribute__((aligned(NLA_ALIGNTO))); + struct genode_wg_nlattr_allowedips allowedips __attribute__((aligned(NLA_ALIGNTO))); +} +__attribute__((aligned(NLA_ALIGNTO), packed)); + + +struct genode_wg_nlattr_peers +{ + struct nlattr header; + struct genode_wg_nlattr_peer peer_0 __attribute__((aligned(NLA_ALIGNTO))); +} +__attribute__((aligned(NLA_ALIGNTO), packed)); + + +static struct genode_wg_net_device _genode_wg_net_dev; +static struct net _genode_wg_src_net; +static struct nlattr *_genode_wg_tb[1]; +static struct nlattr *_genode_wg_data[1]; +static struct netlink_ext_ack _genode_wg_extack; +static struct rtnl_link_ops *_genode_wg_rtnl_link_ops; +static struct genl_family *_genode_wg_genl_family; +static struct socket _genode_wg_socket; + +/* for the call to wg_set_device that installs listen port and private key */ +static struct sock _genode_wg_sock; +static struct sk_buff _genode_wg_sk_buff; +static struct udp_tunnel_sock_cfg _genode_wg_udp_tunnel_cfg; +genode_wg_u16_t _genode_wg_listen_port; + + +genode_wg_u16_t genode_wg_listen_port(void) +{ + return _genode_wg_listen_port; +} + + +void genode_wg_rtnl_link_ops(struct rtnl_link_ops *ops) +{ + _genode_wg_rtnl_link_ops = ops; +} + + +void genode_wg_genl_family(struct genl_family * family) +{ + _genode_wg_genl_family = family; +} + + +struct net_device * genode_wg_net_device(void) +{ + return &_genode_wg_net_dev.public_data; +} + +void genode_wg_udp_tunnel_sock_cfg(struct udp_tunnel_sock_cfg * cfg) +{ + _genode_wg_udp_tunnel_cfg = *cfg; +} + + +/** + * Call 'wg_set_device' in the contrib code + */ +static void +_genode_wg_set_device(struct genl_info *info) +{ + unsigned idx; + bool op_not_found = true; + + for (idx = 0; idx < _genode_wg_genl_family->n_ops; idx++) { + if (_genode_wg_genl_family->ops[idx].cmd == WG_CMD_SET_DEVICE) { + int result = _genode_wg_genl_family->ops[idx].doit(&_genode_wg_sk_buff, info); + if (result != 0) { + printk("Error: op WG_CMD_SET_DEVICE returned %d\n", result); + while (1) { } + } + op_not_found = false; + } + } + if (op_not_found) { + printk("Error: cannot find op WG_CMD_SET_DEVICE\n"); + while (1) { } + } +} + + +void genode_wg_arch_net_dev_init(struct net_device *net_dev, + int *pcpu_refcnt); + + +static void +_genode_wg_config_add_dev(genode_wg_u16_t listen_port, + const genode_wg_u8_t * const priv_key) +{ + static unsigned called = 0; + if (called++) { + printk("%s re-called. Reconfiguration not supported yet\n", __func__); + return; + } + _genode_wg_listen_port = listen_port; + + /* prepare environment for the execution of 'wg_set_device' */ + _genode_wg_net_dev.public_data.rtnl_link_ops = _genode_wg_rtnl_link_ops; + _genode_wg_net_dev.pcpu_refcnt = 0; + genode_wg_arch_net_dev_init( + &_genode_wg_net_dev.public_data, &_genode_wg_net_dev.pcpu_refcnt); + + _genode_wg_sk_buff.sk = &_genode_wg_sock; + _genode_wg_sock.sk_user_data = &_genode_wg_net_dev.private_data; + + { + struct genode_wg_nlattr_ifname ifname; + struct genode_wg_nlattr_u16 port; + struct genode_wg_nlattr_private_key private_key; + struct nlattr * attrs[__WGDEVICE_A_LAST]; + struct genl_info info; + + ifname.data[0] = '\0'; + ifname.header.nla_len = sizeof(ifname); + + port.data = listen_port; + port.header.nla_len = sizeof(port); + + memcpy(private_key.data, priv_key, sizeof(private_key.data)); + + private_key.header.nla_len = sizeof(private_key); + + memset(attrs, 0, sizeof(attrs)); + attrs[WGDEVICE_A_IFNAME] = &ifname.header; + attrs[WGDEVICE_A_LISTEN_PORT] = &port.header; + attrs[WGDEVICE_A_PRIVATE_KEY] = &private_key.header; + + info.attrs = attrs; + _genode_wg_set_device(&info); + } + + /* prepare environment for the execution of 'wg_open' */ + _genode_wg_socket.sk = &_genode_wg_sock; + + /* trigger execution of 'wg_open' */ + _genode_wg_net_dev.public_data.netdev_ops->ndo_open( + &_genode_wg_net_dev.public_data); +} + + +static void _genode_wg_config_rm_dev(genode_wg_u16_t listen_port) +{ + printk("%s not yet implemented\n", __func__); +} + + +static void +_genode_wg_config_add_peer(genode_wg_u16_t listen_port, + genode_wg_u8_t const endpoint_ip[4], + genode_wg_u16_t endpoint_port, + genode_wg_u8_t const *const pub_key, + genode_wg_u8_t const allowed_ip_addr[4], + genode_wg_u8_t const allowed_ip_prefix_length) +{ + struct genode_wg_nlattr_ifname ifname; + struct genode_wg_nlattr_peers peers; + struct nlattr *attrs[__WGDEVICE_A_LAST]; + struct genl_info info; + struct genode_wg_nlattr_peer *peer = &peers.peer_0; + struct genode_wg_nlattr_allowedip *allowedip = &peer->allowedips.ip_0; + + ifname.data[0] = '\0'; + ifname.header.nla_len = sizeof(ifname); + + memset(&peers, 0, sizeof(peers)); + + peers.header.nla_type = WGDEVICE_A_PEERS | NLA_F_NESTED; + peers.header.nla_len = sizeof(peers); + + peer->header.nla_len = sizeof(*peer); + peer->header.nla_type |= NLA_F_NESTED; + + peer->public_key.header.nla_type = WGPEER_A_PUBLIC_KEY; + peer->public_key.header.nla_len = sizeof(peer->public_key); + memcpy(peer->public_key.data, pub_key, sizeof(peer->public_key.data)); + + peer->endpoint.header.nla_type = WGPEER_A_ENDPOINT; + peer->endpoint.header.nla_len = sizeof(peer->endpoint); + peer->endpoint.data.sa_family = AF_INET; + peer->endpoint.data.sa_data[0] = ((genode_wg_u8_t*)&endpoint_port)[1]; + peer->endpoint.data.sa_data[1] = ((genode_wg_u8_t*)&endpoint_port)[0]; + peer->endpoint.data.sa_data[2] = endpoint_ip[0]; + peer->endpoint.data.sa_data[3] = endpoint_ip[1]; + peer->endpoint.data.sa_data[4] = endpoint_ip[2]; + peer->endpoint.data.sa_data[5] = endpoint_ip[3]; + + peer->flags.header.nla_type = WGPEER_A_FLAGS; + peer->flags.header.nla_len = sizeof(peer->flags); + peer->flags.data = 2; /* I don't know what this value means */ + + peer->allowedips.header.nla_len = sizeof(peer->allowedips); + peer->allowedips.header.nla_type = WGPEER_A_ALLOWEDIPS | NLA_F_NESTED; + + allowedip->header.nla_type |= NLA_F_NESTED; + allowedip->header.nla_len = sizeof(*allowedip); + + allowedip->family.header.nla_type = WGALLOWEDIP_A_FAMILY; + allowedip->family.header.nla_len = sizeof(allowedip->family.data) + NLA_HDRLEN; + allowedip->family.data = AF_INET; + + allowedip->ipaddr.header.nla_type = WGALLOWEDIP_A_IPADDR; + allowedip->ipaddr.header.nla_len = sizeof(allowedip->ipaddr.data) + NLA_HDRLEN; + memcpy(&allowedip->ipaddr.data, allowed_ip_addr, 4); + + allowedip->cidr_mask.header.nla_type = WGALLOWEDIP_A_CIDR_MASK; + allowedip->cidr_mask.header.nla_len = sizeof(allowedip->cidr_mask.data) + NLA_HDRLEN; + allowedip->cidr_mask.data = allowed_ip_prefix_length; + + memset(attrs, 0, sizeof(attrs)); + attrs[WGDEVICE_A_IFNAME] = &ifname.header; + attrs[WGDEVICE_A_PEERS] = &peers.header; + + info.attrs = attrs; + _genode_wg_set_device(&info); +} + + +static void +_genode_wg_config_rm_peer(genode_wg_u16_t listen_port, + genode_wg_u8_t const endpoint_ip[4], + genode_wg_u16_t endpoint_port) +{ + printk("%s not yet implemented\n", __func__); +} + + +static struct genode_wg_config_callbacks _config_callbacks = { + .add_device = _genode_wg_config_add_dev, + .remove_device = _genode_wg_config_rm_dev, + .add_peer = _genode_wg_config_add_peer, + .remove_peer = _genode_wg_config_rm_peer +}; + + +static void _genode_wg_uplink_connection_receive(void *buf_base, + genode_wg_size_t buf_size) +{ + struct iphdr * ip; + size_t data_offset; + struct sk_buff *skb = alloc_skb(buf_size, GFP_KERNEL); + if (!skb) { + printk("Error: alloc_skb failed!\n"); + return; + } + + skb_reset_network_header(skb); + memcpy(skb_put(skb, buf_size), buf_base, buf_size); + skb->protocol = htons(ETH_P_IP); + skb->dev = genode_wg_net_device(); + + skb_pull(skb, ETH_HLEN); + skb_reset_network_header(skb); + ip = ip_hdr(skb); + data_offset = ip->ihl * 4; + + genode_wg_net_device()->netdev_ops->ndo_start_xmit(skb, genode_wg_net_device()); +} + + +static void _genode_wg_nic_connection_receive(void *buf_base, + genode_wg_size_t buf_size) +{ + struct iphdr * ip; + size_t data_offset; + struct sk_buff *skb = alloc_skb(buf_size, GFP_KERNEL); + if (!skb) { + printk("Error: alloc_skb failed!\n"); + return; + } + + skb_reset_network_header(skb); + memcpy(skb_put(skb, buf_size), buf_base, buf_size); + skb->protocol = htons(ETH_P_IP); + skb->dev = genode_wg_net_device(); + + skb_pull(skb, ETH_HLEN); + skb_reset_network_header(skb); + ip = ip_hdr(skb); + data_offset = ip->ihl * 4; + + skb_pull(skb, data_offset); + skb_reset_transport_header(skb); + _genode_wg_udp_tunnel_cfg.encap_rcv(&_genode_wg_sock, skb); +} + + +static int user_task_function(void *arg) +{ + for (;;) { + genode_wg_update_config(&_config_callbacks); + + genode_wg_net_receive(&_genode_wg_uplink_connection_receive, + &_genode_wg_nic_connection_receive); + + /* block until lx_emul_task_unblock */ + lx_emul_task_schedule(true); + } + return 0; +} + + +static struct task_struct * _user_task_struct_ptr = NULL; + + +void lx_user_handle_io(void) +{ + if (_user_task_struct_ptr) + lx_emul_task_unblock(_user_task_struct_ptr); +} + + +void genode_wg_arch_lx_user_init(void); + + +void lx_user_init(void) +{ + pid_t pid; + + genode_wg_arch_lx_user_init(); + + skb_init(); + + /* trigger execution of 'wg_setup' */ + _genode_wg_rtnl_link_ops->setup(&_genode_wg_net_dev.public_data); + + /* trigger execution of 'wg_newlink' */ + _genode_wg_rtnl_link_ops->newlink( + &_genode_wg_src_net, + &_genode_wg_net_dev.public_data, + _genode_wg_tb, + _genode_wg_data, + &_genode_wg_extack); + + /* create user task, which handles network traffic and configuration changes */ + pid = kernel_thread(user_task_function, NULL, CLONE_FS | CLONE_FILES); + _user_task_struct_ptr = find_task_by_pid_ns(pid, NULL); +} diff --git a/repos/dde_linux/src/app/wireguard/genode_c_api/wireguard.h b/repos/dde_linux/src/app/wireguard/genode_c_api/wireguard.h new file mode 100644 index 0000000000..e24225af57 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/genode_c_api/wireguard.h @@ -0,0 +1,95 @@ +/* + * \brief Glue code between Genode C++ code and Wireguard C code + * \author Martin Stein + * \date 2022-01-07 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _GENODE_C_API__WIREGUARD_H_ +#define _GENODE_C_API__WIREGUARD_H_ + +enum { GENODE_WG_KEY_LEN = 32 }; + +typedef unsigned char genode_wg_u8_t; +typedef unsigned short genode_wg_u16_t; +typedef unsigned int genode_wg_u32_t; +typedef unsigned long genode_wg_size_t; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*genode_wg_config_add_dev_t) + (genode_wg_u16_t listen_port, const genode_wg_u8_t * const priv_key); + +typedef void (*genode_wg_config_rm_dev_t) (genode_wg_u16_t listen_port); + +typedef void (*genode_wg_config_add_peer_t) ( + genode_wg_u16_t listen_port, + genode_wg_u8_t const endpoint_ip[4], + genode_wg_u16_t endpoint_port, + genode_wg_u8_t const *const pub_key, + genode_wg_u8_t const allowed_ip_addr[4], + genode_wg_u8_t const allowed_ip_prefix +); + +typedef void (*genode_wg_config_rm_peer_t) + (genode_wg_u16_t listen_port, genode_wg_u8_t const endpoint_ip[4], + genode_wg_u16_t endpoint_port); + + +struct genode_wg_config_callbacks +{ + genode_wg_config_add_dev_t add_device; + genode_wg_config_rm_dev_t remove_device; + genode_wg_config_add_peer_t add_peer; + genode_wg_config_rm_peer_t remove_peer; +}; + + +void genode_wg_update_config(struct genode_wg_config_callbacks * callbacks); + + +typedef +void (*genode_wg_uplink_connection_receive_t)(void *buf_base, + genode_wg_size_t buf_size); + + +typedef void (*genode_wg_nic_connection_receive_t)(void *buf_base, + genode_wg_size_t buf_size); + + +void +genode_wg_net_receive(genode_wg_uplink_connection_receive_t uplink_rx_callback, + genode_wg_nic_connection_receive_t nic_rx_callback); + + +genode_wg_u16_t genode_wg_listen_port(void); + + +void genode_wg_send_wg_prot_at_nic_connection( + genode_wg_u8_t const *wg_prot_base, + genode_wg_size_t wg_prot_size, + genode_wg_u16_t udp_src_port_big_endian, + genode_wg_u16_t udp_dst_port_big_endian, + genode_wg_u32_t ipv4_src_addr_big_endian, + genode_wg_u32_t ipv4_dst_addr_big_endian, + genode_wg_u8_t ipv4_dscp_ecn, + genode_wg_u8_t ipv4_ttl); + + +void genode_wg_send_ip_at_uplink_connection( + genode_wg_u8_t const *ip_base, + genode_wg_size_t ip_size); + +#ifdef __cplusplus +} +#endif + +#endif /* _GENODE_C_API__WIREGUARD_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/ipv4_address_prefix.cc b/repos/dde_linux/src/app/wireguard/ipv4_address_prefix.cc new file mode 100644 index 0000000000..a6abae0065 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/ipv4_address_prefix.cc @@ -0,0 +1,103 @@ +/* + * \brief Ipv4 address combined with a subnet prefix length + * \author Martin Stein + * \date 2017-10-12 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* local includes */ +#include + +using namespace Genode; +using namespace Net; + + +Ipv4_address Ipv4_address_prefix::subnet_mask() const +{ + Ipv4_address result; + if (prefix >= 8) { + + result.addr[0] = 0xff; + + if (prefix >= 16) { + + result.addr[1] = 0xff; + + if (prefix >= 24) { + + result.addr[2] = 0xff; + result.addr[3] = 0xff << (32 - prefix); + } else { + result.addr[2] = 0xff << (24 - prefix); + } + } else { + result.addr[1] = 0xff << (16 - prefix); + } + } else { + result.addr[0] = 0xff << (8 - prefix); + } + return result; +} + + +void Ipv4_address_prefix::print(Genode::Output &output) const +{ + Genode::print(output, address, "/", prefix); +} + + +bool Ipv4_address_prefix::prefix_matches(Ipv4_address const &ip) const +{ + uint8_t prefix_left = prefix; + uint8_t byte = 0; + for (; prefix_left >= 8; prefix_left -= 8, byte++) { + if (ip.addr[byte] != address.addr[byte]) { + return false; } + } + if (prefix_left == 0) { + return true; } + + uint8_t const mask = (uint8_t)(~(0xff >> prefix_left)); + return !((ip.addr[byte] ^ address.addr[byte]) & mask); +} + + +Ipv4_address Ipv4_address_prefix::broadcast_address() const +{ + Ipv4_address result = address; + Ipv4_address const mask = subnet_mask(); + for (unsigned i = 0; i < 4; i++) { + result.addr[i] |= (uint8_t)(~mask.addr[i]); + } + return result; +} + + +Ipv4_address_prefix::Ipv4_address_prefix(Ipv4_address address, + Ipv4_address subnet_mask) +: + address(address), prefix(0) +{ + Genode::uint8_t rest; + if (subnet_mask.addr[0] != 0xff) { + rest = subnet_mask.addr[0]; + prefix = 0; + } else if (subnet_mask.addr[1] != 0xff) { + rest = subnet_mask.addr[1]; + prefix = 8; + } else if (subnet_mask.addr[2] != 0xff) { + rest = subnet_mask.addr[2]; + prefix = 16; + } else { + rest = subnet_mask.addr[3]; + prefix = 24; + } + for (Genode::uint8_t mask = 1 << 7; rest & mask; mask >>= 1) + prefix++; +} diff --git a/repos/dde_linux/src/app/wireguard/ipv4_address_prefix.h b/repos/dde_linux/src/app/wireguard/ipv4_address_prefix.h new file mode 100644 index 0000000000..5d031c9666 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/ipv4_address_prefix.h @@ -0,0 +1,82 @@ +/* + * \brief Ipv4 address combined with a subnet prefix length + * \author Martin Stein + * \date 2017-10-12 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _IPV4_ADDRESS_PREFIX_H_ +#define _IPV4_ADDRESS_PREFIX_H_ + +/* Genode includes */ +#include + +namespace Net { + class Ipv4_address_prefix; + + static inline Genode::size_t ascii_to(char const *, Net::Ipv4_address_prefix &); +} + + +struct Net::Ipv4_address_prefix +{ + Ipv4_address address { }; + Genode::uint8_t prefix; + + Ipv4_address_prefix(Ipv4_address address, + Ipv4_address subnet_mask); + + Ipv4_address_prefix() : prefix(32) { } + + bool valid() const { return address.valid() || prefix == 0; } + + void print(Genode::Output &output) const; + + bool prefix_matches(Ipv4_address const &ip) const; + + Ipv4_address subnet_mask() const; + + Ipv4_address broadcast_address() const; + + bool operator != (Ipv4_address_prefix const &other) const + { + return prefix != other.prefix || + address != other.address; + } +}; + + +Genode::size_t Net::ascii_to(char const *s, Ipv4_address_prefix &result) +{ + using namespace Genode; + + /* read the leading IPv4 address, fail if there's no address */ + Net::Ipv4_address_prefix buf; + size_t read_len = ascii_to(s, buf.address); + if (!read_len) { + return 0; } + + /* check for the following slash */ + s += read_len; + if (*s != '/') { + return 0; } + read_len++; + s++; + + /* read the prefix, fail if there's no prefix */ + size_t prefix_len = ascii_to_unsigned(s, buf.prefix, 10); + if (!prefix_len) { + return 0; } + + /* fill result and return read length */ + result = buf; + return read_len + prefix_len; +} + +#endif /* _IPV4_ADDRESS_PREFIX_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/ipv4_config.cc b/repos/dde_linux/src/app/wireguard/ipv4_config.cc new file mode 100644 index 0000000000..dbf137076b --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/ipv4_config.cc @@ -0,0 +1,38 @@ +/* + * \brief IPv4 peer configuration + * \author Martin Stein + * \date 2016-08-19 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* dde_linux wireguard includes */ +#include + +using namespace Genode; +using namespace Net; +using namespace Wireguard; + + +Ipv4_config::Ipv4_config() +: + _interface { } +{ } + + +Ipv4_config::Ipv4_config(Xml_node const &config_node) +: + _interface { config_node.attribute_value("interface", Ipv4_address_prefix()) } +{ } + + +Ipv4_config::Ipv4_config(Dhcp_packet &dhcp_ack) +: + _interface { dhcp_ack.yiaddr(), + dhcp_ipv4_option(dhcp_ack) } +{ } diff --git a/repos/dde_linux/src/app/wireguard/ipv4_config.h b/repos/dde_linux/src/app/wireguard/ipv4_config.h new file mode 100644 index 0000000000..357009614a --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/ipv4_config.h @@ -0,0 +1,59 @@ +/* + * \brief IPv4 peer configuration + * \author Martin Stein + * \date 2016-08-19 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _IPV4_CONFIG_H_ +#define _IPV4_CONFIG_H_ + +/* local includes */ +#include +#include + +/* Genode includes */ +#include + +namespace Wireguard { + + class Ipv4_config; +} + +class Wireguard::Ipv4_config +{ + private: + + Net::Ipv4_address_prefix const _interface; + bool const _interface_valid { _interface.valid() }; + bool const _valid { _interface_valid }; + + public: + + Ipv4_config(Net::Dhcp_packet &dhcp_ack); + + Ipv4_config(Genode::Xml_node const &config_node); + + Ipv4_config(); + + bool operator != (Ipv4_config const &other) const + { + return _interface != other._interface; + } + + + /*************** + ** Accessors ** + ***************/ + + bool valid() const { return _valid; } + Net::Ipv4_address_prefix const &interface() const { return _interface; } +}; + +#endif /* _IPV4_CONFIG_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/irq.cc b/repos/dde_linux/src/app/wireguard/irq.cc new file mode 100644 index 0000000000..c8cc4fcd13 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/irq.cc @@ -0,0 +1,18 @@ + +#include +#include + + +extern "C" void lx_emul_irq_unmask(unsigned int ) { } + + +extern "C" void lx_emul_irq_mask(unsigned int ) { } + + +extern "C" void lx_emul_irq_eoi(unsigned int ) { } + + +extern "C" unsigned int lx_emul_irq_last() +{ + return Lx_kit::env().last_irq; +} diff --git a/repos/dde_linux/src/app/wireguard/list.h b/repos/dde_linux/src/app/wireguard/list.h new file mode 100644 index 0000000000..2fda07d77a --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/list.h @@ -0,0 +1,102 @@ +/* + * \brief Genode list with additional functions needed by NIC router + * \author Martin Stein + * \date 2016-08-19 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _LIST_H_ +#define _LIST_H_ + +/* Genode includes */ +#include +#include + +namespace Net { template class List; } + + +template +struct Net::List : Genode::List +{ + using Base = Genode::List; + + template + void for_each(FUNC && functor) + { + for (LT *elem = Base::first(); elem; ) + { + LT *const next = elem->Base::Element::next(); + functor(*elem); + elem = next; + } + } + + template + void for_each(FUNC && functor) const + { + for (LT const *elem = Base::first(); elem; ) + { + LT const *const next = elem->Base::Element::next(); + functor(*elem); + elem = next; + } + } + + void destroy_each(Genode::Deallocator &dealloc) + { + while (LT *elem = Base::first()) { + Base::remove(elem); + destroy(dealloc, elem); + } + } + + bool empty() const + { + return Base::first() == nullptr; + } + + void insert_as_tail(LT const &le) + { + LT *elem { Base::first() }; + if (elem) { + while (elem->Base::Element::next()) { + elem = elem->Base::Element::next(); + } + } + Base::insert(&le, elem); + } + + bool equal_to(List const &list) const + { + LT const *curr_elem_1 { Base::first() }; + LT const *curr_elem_2 { list.Base::first() }; + while (true) { + + if (curr_elem_1 == nullptr) { + return curr_elem_2 == nullptr; + } + if (curr_elem_2 == nullptr) { + return false; + } + LT const *const next_elem_1 { + curr_elem_1->List::Element::next() }; + + LT const *const next_elem_2 { + curr_elem_2->List::Element::next() }; + + if (!curr_elem_1->equal_to(*curr_elem_2)) { + return false; + } + curr_elem_1 = next_elem_1; + curr_elem_2 = next_elem_2; + } + } +}; + +#endif /* _LIST_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/lx_emul.c b/repos/dde_linux/src/app/wireguard/lx_emul.c new file mode 100644 index 0000000000..730dc18635 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/lx_emul.c @@ -0,0 +1,376 @@ +/** + * \brief Dummy definitions of lx_emul + * \author Stefan Kalkowski + * \date 2022-01-10 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* app/wireguard includes */ +#include + +#include +#include + +void get_random_bytes(void * buf,int nbytes) +{ + lx_emul_random_bytes(buf, nbytes); +} + + +#include + +int wait_for_random_bytes(void) +{ + lx_emul_trace(__func__); + return 0; +} + + +#include + +u32 get_random_u32(void) +{ + u8 buf[4]; + lx_emul_random_bytes(buf, sizeof(buf)); + return *((u32*)&buf); +} + + +#include + +u32 prandom_u32(void) +{ + u8 buf[4]; + lx_emul_random_bytes(buf, sizeof(buf)); + return *((u32*)&buf); +} + + +#include + +int __must_check get_random_bytes_arch(void * buf,int nbytes) +{ + lx_emul_random_bytes(buf, nbytes); + return 0; +} + + +#include + +void * kmalloc_order(size_t size,gfp_t flags,unsigned int order) +{ + return kmalloc(size, flags); +} + + +#include + +void * kvmalloc_node(size_t size,gfp_t flags,int node) +{ + return kmalloc(size, flags); +} + + +#include + +extern void genode_wg_rtnl_link_ops(struct rtnl_link_ops * ops); + +int rtnl_link_register(struct rtnl_link_ops * ops) +{ + genode_wg_rtnl_link_ops(ops); + return 0; +} + + +#include + +extern void genode_wg_genl_family(struct genl_family * family); + +int genl_register_family(struct genl_family * family) +{ + genode_wg_genl_family(family); + return 0; +} + + +#include + +extern struct net_device * genode_wg_net_device(void); + +struct net_device * dev_get_by_name(struct net * net,const char * name) +{ + return genode_wg_net_device(); +} + + +#include + +int udp_sock_create4(struct net * net,struct udp_port_cfg * cfg,struct socket ** sockp) +{ + *sockp = (struct socket*) kmalloc(sizeof(struct socket), GFP_KERNEL); + (*sockp)->sk = (struct sock*) kmalloc(sizeof(struct sock), GFP_KERNEL); + return 0; +} + + +#include + +extern void genode_wg_udp_tunnel_sock_cfg(struct udp_tunnel_sock_cfg * cfg); + +void setup_udp_tunnel_sock(struct net * net,struct socket * sock,struct udp_tunnel_sock_cfg * cfg) +{ + genode_wg_udp_tunnel_sock_cfg(cfg); +} + + +#include + +bool ipv6_mod_enabled(void) +{ + return false; +} + + +#include +#include + +void udp_tunnel_xmit_skb( + struct rtable * rt,struct sock * sk,struct sk_buff * skb, + __be32 src,__be32 dst,__u8 tos,__u8 ttl,__be16 df, + __be16 src_port,__be16 dst_port,bool xnet,bool nocheck) +{ + /* + * FIXME + * + * I don't propagate these values because I found that, at the call to + * udp_tunnel_xmit_skb, Linux sets them hard to the values I'm checking + * for in the following. Furthermore, I assume that they should not be + * relevant for the port anyway. + */ + if (xnet != false) { + pr_info("Error: XNET != false is not expected\n"); + while (1) { } + } + if (nocheck != false) { + pr_info("Error: NOCHECK != false is not expected\n"); + while (1) { } + } + if (df != 0) { + pr_info("Error: DF != 0 is not expected\n"); + while (1) { } + } + /* + * FIXME + * + * Manually set TTL. In the Linux reference scenario this argument is + * observed to be 64. Here it is 0. Further Linux contrib code would have + * to be incorporated in order to make Wireguard provide a correct TTL + * argument. However, it is simpler to set it manually. + */ + if (ttl != 0) { + pr_info("Error: TTL != 0 is not expected\n"); + while (1) { } + } + ttl = 64; + + /* + * FIXME + * + * Manually set UDP destination port. In the Linux reference scenario this + * argument is observed to be the listen port. Here it is som other port. + * Further Linux contrib code would have to be incorporated in order to + * make Wireguard provide a correct argument. However, it is simpler to + * set it manually. + */ + src_port = htons(genode_wg_listen_port()); + + /* + * This is the SKB that we put into WireGuard earlier in + * _genode_wg_uplink_connection_receive. WireGuard modified it to become + * the SKB that we want to send at the NIC connection. WireGuard + * assumes that we free the SKB after having sent it. + */ + genode_wg_send_wg_prot_at_nic_connection( + skb->data, skb->len, src_port, dst_port, src, dst, + tos, ttl); + + kfree_skb(skb); +} + + +#include + +DEFINE_STATIC_KEY_FALSE(memalloc_socks_key); +EXPORT_SYMBOL_GPL(memalloc_socks_key); + + +#include + +struct kmem_cache * kmem_cache_create_usercopy(const char * name, + unsigned int size, + unsigned int align, + slab_flags_t flags, + unsigned int useroffset, + unsigned int usersize, + void (* ctor)(void *)) +{ + return kmem_cache_create(name, size, align, flags, ctor); +} + + +#include + +/* Returns either the correct skb->protocol value, or 0 if invalid. */ +__be16 ip_tunnel_parse_protocol(const struct sk_buff *skb) +{ + //FIXME: we just assume IPv4 + return htons(ETH_P_IP); +} + + +#include + +bool rng_is_initialized(void) +{ + return true; +} + + +#include + +__be32 inet_confirm_addr(struct net * net,struct in_device * in_dev,__be32 dst,__be32 local,int scope) +{ + lx_emul_trace(__func__); + return local; +} + + +#include + +struct rtable * ip_route_output_flow(struct net * net,struct flowi4 * flp4,const struct sock * sk) +{ + static bool initialized = false; + static struct dst_metrics dst_default_metrics; + static struct rtable rt; + if (!initialized) { + rt.dst.dev = genode_wg_net_device(); + dst_init_metrics(&rt.dst, dst_default_metrics.metrics, true); + initialized = true; + } + return &rt; +} + + +#include + +int __cond_resched(void) +{ + if (should_resched(0)) { + schedule(); + return 1; + } + return 0; +} + + +#include + +void call_rcu(struct rcu_head * head,rcu_callback_t func) +{ + func(head); +} + + +#include + +void kfree_sensitive(const void * p) +{ + kfree(p); +} + + +#include + +gro_result_t napi_gro_receive(struct napi_struct * napi,struct sk_buff * skb) +{ + /* + * This is the SKB that we put into WireGuard earlier in + * _genode_wg_nic_connection_receive. WireGuard modified it to become + * the SKB that we want to send at the Uplink connection. WireGuard + * assumes that we free the SKB after having sent it. + */ + genode_wg_send_ip_at_uplink_connection(skb->data, skb->len); + kfree_skb(skb); + + /* + * FIXME + * + * The Wireguard contrib code currently ignores this return value. + * Considering the possibility that, one day, it does otherwise, I return + * an invalid value here in the hope that it complains. The reason is that + * I don't understand GRO and its return values fully and don't want to + * dive into it because I hope that it will not become relevant anyway. + */ + return -1; +} + + +#include + +void netif_napi_add(struct net_device * dev,struct napi_struct * napi,int (* poll)(struct napi_struct *,int),int weight) +{ + napi->dev = dev; + napi->poll = poll; + napi->weight = weight; +} + + +#include + +bool napi_schedule_prep(struct napi_struct * n) +{ + return true; +} + + +#include + +void __napi_schedule(struct napi_struct * n) +{ + int weight = n->weight; + if (n->poll(n, n->weight) >= weight) { + printk("Warning: more work to do?\n"); + lx_emul_trace_and_stop(__func__); + } +} + + +#include + +bool napi_complete_done(struct napi_struct * n,int work_done) +{ + lx_emul_trace(__func__); + return true; +} + + +#include + +void __do_once_done(bool * done,struct static_key_true * once_key,unsigned long * flags,struct module * mod) +{ + *done = true; +} + + +#include + +bool __do_once_start(bool * done,unsigned long * flags) +{ + return !*done; +} diff --git a/repos/dde_linux/src/app/wireguard/lx_emul.h b/repos/dde_linux/src/app/wireguard/lx_emul.h new file mode 100644 index 0000000000..772e5d6e52 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/lx_emul.h @@ -0,0 +1,23 @@ +/** + * \brief Dummy definitions of Linux Kernel functions + * \author Stefan Kalkowski + * \date 2022-01-07 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* Needed to trace and stop */ +#include + +/* fix for missing includes in generated_dummies */ +#include +#include +#include + + +struct rtnl_link_ops *wireguard_rtnl_link_ops(void); diff --git a/repos/dde_linux/src/app/wireguard/lx_emul/alloc.cc b/repos/dde_linux/src/app/wireguard/lx_emul/alloc.cc new file mode 100644 index 0000000000..1458d18fe1 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/lx_emul/alloc.cc @@ -0,0 +1,84 @@ +/* + * \brief This file shadows repos/dde_linux/src/lib/lx_emul/alloc.cc + * \author Martin Stein + * \author Stefan Kalkowski + * \date 2021-03-22 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include +#include +#include +#include + +extern "C" void * lx_emul_mem_alloc_aligned(unsigned long size, unsigned long align) +{ + void * const ptr = Lx_kit::env().memory.alloc(size, align); + return ptr; +}; + + +extern "C" void * lx_emul_mem_alloc_aligned_uncached(unsigned long size, + unsigned long align) +{ + void * const ptr = Lx_kit::env().uncached_memory.alloc(size, align); + return ptr; +}; + + +extern "C" unsigned long lx_emul_mem_dma_addr(void * addr) +{ + return (unsigned long)addr; +} + + +extern "C" unsigned long lx_emul_mem_virt_addr(void * dma_addr) +{ + return (unsigned long)dma_addr; +} + + +extern "C" void lx_emul_mem_free(const void * ptr) +{ + if (!ptr) + return; + if (Lx_kit::env().memory.free(ptr)) + return; + if (Lx_kit::env().uncached_memory.free(ptr)) + return; + Genode::error(__func__, " called with invalid ptr ", ptr); +}; + + +extern "C" unsigned long lx_emul_mem_size(const void * ptr) +{ + unsigned long ret = 0; + if (!ptr) + return ret; + if ((ret = Lx_kit::env().memory.size(ptr))) + return ret; + if (!(ret = Lx_kit::env().uncached_memory.size(ptr))) + Genode::error(__func__, " called with invalid ptr ", ptr); + return ret; +}; + + +extern "C" void lx_emul_mem_cache_clean_invalidate(const void * addr, + unsigned long size) +{ + Genode::cache_clean_invalidate_data((Genode::addr_t)addr, size); +} + + +extern "C" void lx_emul_mem_cache_invalidate(const void * addr, + unsigned long size) +{ + Genode::cache_invalidate_data((Genode::addr_t)addr, size); +} diff --git a/repos/dde_linux/src/app/wireguard/lx_emul/random.h b/repos/dde_linux/src/app/wireguard/lx_emul/random.h new file mode 100644 index 0000000000..9ed5f1eef0 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/lx_emul/random.h @@ -0,0 +1,27 @@ +/** + * \brief Randomness generation of lx_emul + * \author Stefan Kalkowski + * \date 2022-01-12 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#ifndef _LX_EMUL__RANDOM_H_ +#define _LX_EMUL__RANDOM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void lx_emul_random_bytes(void * buf, int bytes); + +#ifdef __cplusplus +} +#endif + +#endif /* _LX_EMUL__RANDOM_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/lx_emul/shadow/arch/arm64/kernel/cpufeature.c b/repos/dde_linux/src/app/wireguard/lx_emul/shadow/arch/arm64/kernel/cpufeature.c new file mode 100644 index 0000000000..efd26487a8 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/lx_emul/shadow/arch/arm64/kernel/cpufeature.c @@ -0,0 +1,37 @@ +/* + * \brief Replaces arch/arm64/kernel/cpufeature.c + * \author Martin Stein + * \date 2022-05-09 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include + +/* + * Flag to indicate if we have computed the system wide + * capabilities based on the boot time active CPUs. This + * will be used to determine if a new booting CPU should + * go through the verification process to make sure that it + * supports the system capabilities, without using a hotplug + * notifier. This is also used to decide if we could use + * the fast path for checking constant CPU caps. + */ +DEFINE_STATIC_KEY_FALSE(arm64_const_caps_ready); +EXPORT_SYMBOL(arm64_const_caps_ready); +void finalize_system_capabilities(void) +{ + static_branch_enable(&arm64_const_caps_ready); +} + +DEFINE_STATIC_KEY_ARRAY_FALSE(cpu_hwcap_keys, ARM64_NCAPS); +EXPORT_SYMBOL(cpu_hwcap_keys); + +DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS); +EXPORT_SYMBOL(cpu_hwcaps); diff --git a/repos/dde_linux/src/app/wireguard/lx_kit/device.h b/repos/dde_linux/src/app/wireguard/lx_kit/device.h new file mode 100644 index 0000000000..9093d97c25 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/lx_kit/device.h @@ -0,0 +1,28 @@ +#ifndef _LX_KIT__DEVICE_H_ +#define _LX_KIT__DEVICE_H_ + +#include +#include + +namespace Platform { struct Connection; } +namespace Lx_kit { struct Device_list; } + +struct Platform::Connection +{ + Connection(Genode::Env &) {} +}; + + +struct Lx_kit::Device_list +{ + Device_list(Genode::Entrypoint &, + Genode::Heap &, + Platform::Connection &) {} + + void update() {} + + template + void for_each(FN const &) {} +}; + +#endif /* _LX_KIT__DEVICE_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/lx_kit/memory.cc b/repos/dde_linux/src/app/wireguard/lx_kit/memory.cc new file mode 100644 index 0000000000..df48c99a8f --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/lx_kit/memory.cc @@ -0,0 +1,171 @@ +/* + * \brief This file shadows repos/dde_linux/src/lib/lx_kit/memory.cc + * \author Martin Stein + * \author Stefan Kalkowski + * \date 2021-03-25 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* Genode includes */ +#include + +/* local includes */ +#include +#include +#include +#include + + +void Lx_kit::Mem_allocator::free_buffer(void * addr) +{ + Buffer * buffer = nullptr; + + _virt_to_dma.apply(Buffer_info::Query_addr(addr), + [&] (Buffer_info const & info) { + buffer = &info.buffer; + }); + + if (!buffer) { + warning(__func__, ": no memory buffer for addr: ", addr, " found"); + return; + } + + void const * virt_addr = (void const *)buffer->virt_addr(); + void const * dma_addr = (void const *)buffer->dma_addr(); + + _virt_to_dma.remove(Buffer_info::Query_addr(virt_addr)); + _dma_to_virt.remove(Buffer_info::Query_addr(dma_addr)); + + destroy(_heap, buffer); +} + + +Genode::Dataspace_capability Lx_kit::Mem_allocator::attached_dataspace_cap(void * addr) +{ + Genode::Dataspace_capability ret { }; + + _virt_to_dma.apply(Buffer_info::Query_addr(addr), + [&] (Buffer_info const & info) { + ret = info.buffer.cap(); + }); + + return ret; +} + + +void * Lx_kit::Mem_allocator::alloc(size_t size, size_t align) +{ + if (!size) + return nullptr; + + return _mem.alloc_aligned(size, (unsigned)log2(align)).convert( + + [&] (void *ptr) { + memset(ptr, 0, size); + return ptr; }, + + [&] (Range_allocator::Alloc_error) { + + /* + * Restrict the minimum buffer size to avoid the creation of + * a separate dataspaces for tiny allocations. + */ + size_t const min_buffer_size = 256*1024; + + /* + * Allocate one excess byte that is not officially registered at + * the '_mem' ranges. This way, two virtual consecutive ranges + * (that must be assumed to belong to non-contiguous physical + * ranges) can never be merged when freeing an allocation. Such + * a merge would violate the assumption that a both the virtual + * and physical addresses of a multi-page allocation are always + * contiguous. + */ + Buffer & buffer = alloc_buffer(max(size + 1, min_buffer_size)); + + _mem.add_range(buffer.virt_addr(), buffer.size() - 1); + + lx_emul_forget_pages((void*)buffer.virt_addr(), buffer.size()); + lx_emul_virt_to_pages((void*)buffer.virt_addr(), (buffer.size() + 0xfff) >> 12); + + /* re-try allocation */ + return _mem.alloc_aligned(size, (unsigned)log2(align)).convert( + + [&] (void *ptr) { + memset(ptr, 0, size); + return ptr; }, + + [&] (Range_allocator::Alloc_error) -> void * { + error("memory allocation failed for ", size, " align ", align); + return nullptr; } + ); + } + ); +} + + +Genode::addr_t Lx_kit::Mem_allocator::dma_addr(void * addr) +{ + addr_t ret = 0UL; + + _virt_to_dma.apply(Buffer_info::Query_addr(addr), + [&] (Buffer_info const & info) { + addr_t const offset = (addr_t)addr - info.buffer.virt_addr(); + ret = info.buffer.dma_addr() + offset; + }); + + return ret; +} + + +Genode::addr_t Lx_kit::Mem_allocator::virt_addr(void * dma_addr) +{ + addr_t ret = 0UL; + + _dma_to_virt.apply(Buffer_info::Query_addr(dma_addr), + [&] (Buffer_info const & info) { + addr_t const offset = (addr_t)dma_addr - info.buffer.dma_addr(); + ret = info.buffer.virt_addr() + offset; + }); + + return ret; +} + + +bool Lx_kit::Mem_allocator::free(const void * ptr) +{ + if (!_mem.valid_addr((addr_t)ptr)) + return false; + + using Size_at_error = Allocator_avl::Size_at_error; + + _mem.size_at(ptr).with_result( + [&] (size_t) { _mem.free(const_cast(ptr)); }, + [ ] (Size_at_error) { }); + + return true; +} + + +Genode::size_t Lx_kit::Mem_allocator::size(const void * ptr) +{ + if (!ptr) return 0; + + using Size_at_error = Allocator_avl::Size_at_error; + + return _mem.size_at(ptr).convert([ ] (size_t s) { return s; }, + [ ] (Size_at_error) { return 0U; }); +} + + +Lx_kit::Mem_allocator::Mem_allocator(Genode::Env & env, + Heap & heap, + Platform::Connection & platform, + Cache cache_attr) +: _env(env), _heap(heap), _platform(platform), _cache_attr(cache_attr) {} diff --git a/repos/dde_linux/src/app/wireguard/main.cc b/repos/dde_linux/src/app/wireguard/main.cc new file mode 100644 index 0000000000..805bcc6590 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/main.cc @@ -0,0 +1,255 @@ +/* + * \brief Wireguard component + * \author Stefan Kalkowski + * \author Martin Stein + * \date 2022-01-07 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#include +#include + +/* base includes */ +#include +#include +#include +#include + +/* lx-kit includes */ +#include + +/* lx-emul includes */ +#include + +/* lx-user includes */ +#include + +/* app/wireguard includes */ +#include +#include +#include + +using namespace Genode; + +namespace Wireguard { class Main; } + + +class Wireguard::Main : private Entrypoint::Io_progress_handler, + private Nic_connection_notifier +{ + private: + + Env &_env; + Timer::Connection _timer { _env }; + Heap _heap { _env.ram(), _env.rm() }; + Attached_rom_dataspace _config_rom { _env, "config" }; + Signal_handler
_config_handler { _env.ep(), *this, &Main::_handle_config }; + Io_signal_handler
_signal_handler { _env.ep(), *this, &Main::_handle_signal }; + Config_model _config_model { _heap }; + Signal_handler
_nic_ip_config_handler { _env.ep(), *this, &Main::_handle_nic_ip_config }; + Nic_connection _nic_connection { _env, _heap, _signal_handler, _config_rom.xml(), _timer, *this }; + Constructible _uplink_connection { }; + + void _handle_signal() + { + lx_user_handle_io(); + Lx_kit::env().scheduler.schedule(); + } + + void _handle_config() { _config_rom.update(); } + + void _handle_nic_ip_config(); + + + /***************************** + ** Nic_connection_notifier ** + *****************************/ + + void notify_about_ip_config_update() override + { + _nic_ip_config_handler.local_submit(); + } + + public: + + Main(Env &env) + : + _env(env) + { + Lx_kit::initialize(_env); + + /* + * We have to call the static constructors because otherwise the + * initcall list of the LX kit won't get populated. + */ + _env.exec_static_constructors(); + + _config_rom.sigh(_config_handler); + _handle_config(); + + env.ep().register_io_progress_handler(*this); + + /* trigger signal handling once after construction */ + Signal_transmitter(_signal_handler).submit(); + } + + /** + * Entrypoint::Io_progress_handler + */ + void handle_io_progress() override + { + if (_uplink_connection.constructed()) { + _uplink_connection->notify_peer(); + } + _nic_connection.notify_peer(); + } + + void update(genode_wg_config_callbacks & callbacks) + { + _config_model.update(callbacks, _config_rom.xml()); + } + + void net_receive(genode_wg_uplink_connection_receive_t uplink_rcv_callback, + genode_wg_nic_connection_receive_t nic_rcv_callback) + { + if (_uplink_connection.constructed()) { + _uplink_connection->for_each_rx_packet(uplink_rcv_callback); + } + _nic_connection.for_each_rx_packet(nic_rcv_callback); + } + + void send_wg_prot_at_nic_connection( + genode_wg_u8_t const *wg_prot_base, + genode_wg_size_t wg_prot_size, + genode_wg_u16_t udp_src_port_big_endian, + genode_wg_u16_t udp_dst_port_big_endian, + genode_wg_u32_t ipv4_src_addr_big_endian, + genode_wg_u32_t ipv4_dst_addr_big_endian, + genode_wg_u8_t ipv4_dscp_ecn, + genode_wg_u8_t ipv4_ttl); + + void send_ip_at_uplink_connection( + genode_wg_u8_t const *ip_base, + genode_wg_size_t ip_size); +}; + + +void Wireguard::Main::_handle_nic_ip_config() +{ + if (_nic_connection.ip_config().valid()) { + if (!_uplink_connection.constructed()) { + _uplink_connection.construct(_env, _heap, _signal_handler); + } + } else { + if (_uplink_connection.constructed()) { + _uplink_connection.destruct(); + } + } +} + + +void Wireguard::Main::send_wg_prot_at_nic_connection( + genode_wg_u8_t const *wg_prot_base, + genode_wg_size_t wg_prot_size, + genode_wg_u16_t udp_src_port_big_endian, + genode_wg_u16_t udp_dst_port_big_endian, + genode_wg_u32_t ipv4_src_addr_big_endian, + genode_wg_u32_t ipv4_dst_addr_big_endian, + genode_wg_u8_t ipv4_dscp_ecn, + genode_wg_u8_t ipv4_ttl) +{ + _nic_connection.send_wg_prot( + wg_prot_base, + wg_prot_size, + udp_src_port_big_endian, + udp_dst_port_big_endian, + ipv4_src_addr_big_endian, + ipv4_dst_addr_big_endian, + ipv4_dscp_ecn, + ipv4_ttl); +} + + +void Wireguard::Main::send_ip_at_uplink_connection( + genode_wg_u8_t const *ip_base, + genode_wg_size_t ip_size) +{ + if (_uplink_connection.constructed()) { + _uplink_connection->send_ip(ip_base, ip_size); + } else { + log("Main: drop packet - uplink connection down"); + } +} + + +static Wireguard::Main & main_object(Genode::Env & env) +{ + static Wireguard::Main main { env }; + return main; +} + + +extern "C" void +genode_wg_update_config(struct genode_wg_config_callbacks * callbacks) +{ + main_object(Lx_kit::env().env).update(*callbacks); +}; + + +extern "C" void +genode_wg_net_receive(genode_wg_uplink_connection_receive_t uplink_rcv_callback, + genode_wg_nic_connection_receive_t nic_rcv_callback) +{ + main_object(Lx_kit::env().env).net_receive(uplink_rcv_callback, + nic_rcv_callback); +} + + +void genode_wg_send_wg_prot_at_nic_connection( + genode_wg_u8_t const *wg_prot_base, + genode_wg_size_t wg_prot_size, + genode_wg_u16_t udp_src_port_big_endian, + genode_wg_u16_t udp_dst_port_big_endian, + genode_wg_u32_t ipv4_src_addr_big_endian, + genode_wg_u32_t ipv4_dst_addr_big_endian, + genode_wg_u8_t ipv4_dscp_ecn, + genode_wg_u8_t ipv4_ttl) +{ + main_object(Lx_kit::env().env).send_wg_prot_at_nic_connection( + wg_prot_base, + wg_prot_size, + udp_src_port_big_endian, + udp_dst_port_big_endian, + ipv4_src_addr_big_endian, + ipv4_dst_addr_big_endian, + ipv4_dscp_ecn, + ipv4_ttl); +} + + +void genode_wg_send_ip_at_uplink_connection( + genode_wg_u8_t const *ip_base, + genode_wg_size_t ip_size) +{ + main_object(Lx_kit::env().env).send_ip_at_uplink_connection( + ip_base, + ip_size); +} + + +void Component::construct(Env &env) +{ + main_object(env); + + /* + * Main needs to be constructed before startin Linux code, + * because of genode_wg_* calls + */ + lx_emul_start_kernel(nullptr); +} diff --git a/repos/dde_linux/src/app/wireguard/nic_connection.cc b/repos/dde_linux/src/app/wireguard/nic_connection.cc new file mode 100644 index 0000000000..aad650fbfe --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/nic_connection.cc @@ -0,0 +1,339 @@ +/* + * \brief Network back-end towards public network (encrypted UDP tunnel) + * \author Stefan Kalkowski + * \author Martin Stein + * \date 2022-01-07 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* dde_linux wireguard includes */ +#include + +/* os includes */ +#include + +using namespace Genode; +using namespace Net; +using namespace Wireguard; + + +Nic_connection::Handle_pkt_result +Nic_connection::_drop_pkt(char const *packet_type, + char const *reason) +{ + if (_verbose_pkt_drop) { + log("Drop ", packet_type, " - ", reason); + } + return Handle_pkt_result::DROP_PACKET; +} + + +void Nic_connection::_connection_tx_flush_acks() +{ + while (_connection.tx()->ack_avail()) { + _connection.tx()->release_packet( + _connection.tx()->get_acked_packet()); + } +} + + +Nic_connection::Send_pkt_result +Nic_connection::_finish_send_eth_ipv4_with_eth_dst_set_via_arp(Packet_descriptor pkt, + Mac_address const ð_dst) +{ + void *pkt_base { _connection.tx()->packet_content(pkt) }; + Size_guard size_guard { pkt.size() }; + + Ethernet_frame ð { Ethernet_frame::cast_from(pkt_base, size_guard) }; + + eth.dst(eth_dst); + _connection_tx_flush_acks(); + _connection.tx()->submit_packet(pkt); + return Send_pkt_result::SUCCEEDED; +} + + +Nic_connection::Send_pkt_result +Nic_connection::_send_arp_reply(Ethernet_frame &request_eth, + Arp_packet &request_arp) +{ + return send(ARP_PACKET_SIZE, [&] (void *reply_base, Size_guard &reply_guard) { + + Ethernet_frame &reply_eth { + Ethernet_frame::construct_at(reply_base, reply_guard) }; + + reply_eth.dst(request_eth.src()); + reply_eth.src(_mac_address); + reply_eth.type(Ethernet_frame::Type::ARP); + + Arp_packet &reply_arp { + reply_eth.construct_at_data(reply_guard) }; + + reply_arp.hardware_address_type(Arp_packet::ETHERNET); + reply_arp.protocol_address_type(Arp_packet::IPV4); + reply_arp.hardware_address_size(sizeof(Mac_address)); + reply_arp.protocol_address_size(sizeof(Ipv4_address)); + reply_arp.opcode(Arp_packet::REPLY); + reply_arp.src_mac(_mac_address); + reply_arp.src_ip(request_arp.dst_ip()); + reply_arp.dst_mac(request_arp.src_mac()); + reply_arp.dst_ip(request_arp.src_ip()); + }); +} + + +Nic_connection::Handle_pkt_result +Nic_connection::_handle_arp_request(Ethernet_frame ð, + Arp_packet &arp) +{ + if (ip_config().interface().address != arp.dst_ip()) { + return _drop_pkt("ARP request", "Doesn't target my IP address"); + } + if (_send_arp_reply(eth, arp) != Send_pkt_result::SUCCEEDED) { + return _drop_pkt("ARP request", "Sending reply failed"); + } + return Handle_pkt_result::ACK_PACKET; +} + + +Nic_connection::Handle_pkt_result +Nic_connection::_handle_arp(Ethernet_frame ð, + Size_guard &size_guard) +{ + Arp_packet &arp { eth.data(size_guard) }; + if (!arp.ethernet_ipv4()) { + return _drop_pkt("ARP packet", "Targets unknown protocol"); + } + switch (arp.opcode()) { + case Arp_packet::REQUEST: return _handle_arp_request(eth, arp); + case Arp_packet::REPLY: return _handle_arp_reply(arp); + default: return _drop_pkt("ARP packet", "Unexpected opcode"); + } +} + + +void Nic_connection::_broadcast_arp_request(Ipv4_address const &src_ip, + Ipv4_address const &dst_ip) +{ + send(ARP_PACKET_SIZE, [&] (void *pkt_base, Size_guard &size_guard) { + + /* write Ethernet header */ + Ethernet_frame ð = Ethernet_frame::construct_at(pkt_base, size_guard); + eth.dst(Mac_address(0xff)); + eth.src(_mac_address); + eth.type(Ethernet_frame::Type::ARP); + + /* write ARP header */ + Arp_packet &arp = eth.construct_at_data(size_guard); + arp.hardware_address_type(Arp_packet::ETHERNET); + arp.protocol_address_type(Arp_packet::IPV4); + arp.hardware_address_size(sizeof(Mac_address)); + arp.protocol_address_size(sizeof(Ipv4_address)); + arp.opcode(Arp_packet::REQUEST); + arp.src_mac(_mac_address); + arp.src_ip(src_ip); + arp.dst_mac(Mac_address(0xff)); + arp.dst_ip(dst_ip); + }); +} + + +Nic_connection::Handle_pkt_result +Nic_connection::_handle_arp_reply(Arp_packet &arp) +{ + _arp_cache.find_by_ip(arp.src_ip()).with_result( + [&] (Const_pointer) { }, + [&] (Arp_cache_error) { + + /* by now, no matching ARP cache entry exists, so create one */ + Ipv4_address const ip = arp.src_ip(); + _arp_cache.new_entry(ip, arp.src_mac()); + + /* finish sending packets that waited for the entry */ + for (Arp_waiter_list_element *waiter_le = _arp_waiters.first(); + waiter_le; ) { + + Arp_waiter &waiter = *waiter_le->object(); + waiter_le = waiter_le->next(); + if (ip != waiter.ip()) { + continue; + } + _finish_send_eth_ipv4_with_eth_dst_set_via_arp( + waiter.packet(), arp.src_mac()); + + destroy(_alloc, &waiter); + } + } + ); + return Handle_pkt_result::ACK_PACKET; +} + + +Nic_connection::Nic_connection(Env &env, + Allocator &alloc, + Signal_context_capability pkt_stream_sigh, + Xml_node const &config_node, + Timer::Connection &timer, + Nic_connection_notifier ¬ifier) +: + _alloc { alloc }, + _notifier { notifier }, + _dhcp_client { timer, *this }, + _ip_config { config_node }, + _connection { env, &_packet_alloc, BUF_SIZE, BUF_SIZE, + "nic_session" }, + _link_state_handler { env.ep(), *this, &Nic_connection::_handle_link_state } +{ + _connection.rx_channel()->sigh_ready_to_ack(pkt_stream_sigh); + _connection.rx_channel()->sigh_packet_avail(pkt_stream_sigh); + _connection.tx_channel()->sigh_ack_avail(pkt_stream_sigh); + _connection.tx_channel()->sigh_ready_to_submit(pkt_stream_sigh); + _connection.link_state_sigh(_link_state_handler); + + if (ip_config().valid()) { + _notifier.notify_about_ip_config_update(); + } else { + _dhcp_client.discover(); + } +} + + +void Nic_connection::_handle_link_state() +{ + discard_ip_config(); + _dhcp_client.discover(); +} + + +void Nic_connection::for_each_rx_packet(Handle_packet_func handle_packet) +{ + typename Nic::Connection::Rx::Sink & rx_sink = *_connection.rx(); + + for (;;) { + + if (!rx_sink.packet_avail() || !rx_sink.ack_slots_free()) + break; + + Packet_descriptor const packet = rx_sink.peek_packet(); + + bool const packet_valid = rx_sink.packet_valid(packet) + && (packet.offset() >= 0); + + if (packet_valid) { + + void *eth_base { rx_sink.packet_content(packet) }; + Size_guard size_guard { packet.size() }; + Ethernet_frame ð { Ethernet_frame::cast_from(eth_base, size_guard) }; + + if (!ip_config().valid()) { + + _dhcp_client.handle_eth(eth, size_guard); + + } else { + + switch (eth.type()) { + case Ethernet_frame::Type::ARP: + + _handle_arp(eth, size_guard); + break; + + case Ethernet_frame::Type::IPV4: + + handle_packet(eth_base, packet.size()); + _notify_peers = true; + break; + + default: + + _drop_pkt("packet", "Unknown type in Ethernet header"); + break; + } + } + } + (void)rx_sink.try_get_packet(); + rx_sink.try_ack_packet(packet); + } +} + + +void Nic_connection::notify_peer() +{ + if (_notify_peers) { + _notify_peers = false; + _connection.rx()->wakeup(); + _connection.tx()->wakeup(); + } +} + + +void Nic_connection::discard_ip_config() +{ + _ip_config.construct(); + _notifier.notify_about_ip_config_update(); +} + + +void Nic_connection::ip_config_from_dhcp_ack(Net::Dhcp_packet &dhcp_ack) +{ + _ip_config.construct(dhcp_ack); + _notifier.notify_about_ip_config_update(); +} + + +void +Nic_connection::send_wg_prot(uint8_t const *wg_prot_base, + size_t wg_prot_size, + uint16_t udp_src_port_big_endian, + uint16_t udp_dst_port_big_endian, + uint32_t, + uint32_t ipv4_dst_addr_big_endian, + uint8_t ipv4_dscp_ecn, + uint8_t ipv4_ttl) +{ + size_t const pkt_size { + sizeof(Ethernet_frame) + sizeof(Ipv4_packet) + sizeof(Udp_packet) + + wg_prot_size }; + + Ipv4_address const dst_ip { + Ipv4_address::from_uint32_big_endian(ipv4_dst_addr_big_endian) }; + + _send_eth_ipv4_with_eth_dst_set_via_arp( + pkt_size, dst_ip, [&] (Ethernet_frame ð, Size_guard &size_guard) + { + /* create ETH header */ + eth.src(_mac_address); + eth.type(Ethernet_frame::Type::IPV4); + + /* create IP header of the reply */ + size_t const ip_off = size_guard.head_size(); + Ipv4_packet &ip = eth.construct_at_data(size_guard); + ip.header_length(sizeof(Ipv4_packet) / 4); + ip.version(4); + ip.time_to_live(ipv4_ttl); + ip.diff_service_ecn(ipv4_dscp_ecn); + ip.protocol(Ipv4_packet::Protocol::UDP); + ip.src_big_endian(ip_config().interface().address.to_uint32_big_endian()); + ip.dst_big_endian(ipv4_dst_addr_big_endian); + + /* create UDP header of the reply */ + size_t const udp_off = size_guard.head_size(); + Udp_packet &udp = ip.construct_at_data(size_guard); + udp.src_port_big_endian(udp_src_port_big_endian); + udp.dst_port_big_endian(udp_dst_port_big_endian); + + /* add Wireguard protocol data */ + udp.memcpy_to_data((void *)wg_prot_base, wg_prot_size, size_guard); + + /* fill in header values that need the packet to be complete already */ + udp.length((uint16_t)(size_guard.head_size() - udp_off)); + udp.update_checksum(ip.src(), ip.dst()); + ip.total_length(size_guard.head_size() - ip_off); + ip.update_checksum(); + }); +} diff --git a/repos/dde_linux/src/app/wireguard/nic_connection.h b/repos/dde_linux/src/app/wireguard/nic_connection.h new file mode 100644 index 0000000000..cda21ffc11 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/nic_connection.h @@ -0,0 +1,224 @@ +/* + * \brief Network back-end towards public network (encrypted UDP tunnel) + * \author Stefan Kalkowski + * \author Martin Stein + * \date 2022-01-07 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _NIC_CONNECTION_H_ +#define _NIC_CONNECTION_H_ + +/* base includes */ +#include + +/* os includes */ +#include +#include +#include +#include + +/* dde_linux wireguard includes */ +#include +#include +#include +#include +#include + +namespace Timer +{ + class Connection; +} + +namespace Net { + + class Dhcp_packet; +} + +namespace Wireguard { + + class Nic_connection_notifier; + class Nic_connection; +} + + +class Wireguard::Nic_connection_notifier : Genode::Interface +{ + public: + + virtual void notify_about_ip_config_update() = 0; +}; + + +class Wireguard::Nic_connection +{ + private: + + using Handle_packet_func = void (*)(void *buf_base, + Genode::size_t buf_size); + + using Packet_source = Nic::Packet_stream_source<::Nic::Session::Policy>; + + enum { PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE }; + enum { WG_PROT_PACKET_SIZE = Nic::Packet_allocator::OFFSET_PACKET_SIZE }; + enum { BUF_SIZE = Nic::Connection::Session::QUEUE_SIZE * PACKET_SIZE }; + + enum { + + ETHERNIC_CONNECTION_HEADER_SIZE = sizeof(Net::Ethernet_frame), + + ETHERNIC_CONNECTION_DATA_SIZE_WITH_ARP = + sizeof(Net::Arp_packet) + ETHERNIC_CONNECTION_HEADER_SIZE < Net::Ethernet_frame::MIN_SIZE ? + Net::Ethernet_frame::MIN_SIZE - ETHERNIC_CONNECTION_HEADER_SIZE : + sizeof(Net::Arp_packet), + + ETHERNIC_CONNECTION_CRC_SIZE = sizeof(Genode::uint32_t), + + ARP_PACKET_SIZE = + ETHERNIC_CONNECTION_HEADER_SIZE + + ETHERNIC_CONNECTION_DATA_SIZE_WITH_ARP + + ETHERNIC_CONNECTION_CRC_SIZE, + }; + + enum Handle_pkt_result { DROP_PACKET, ACK_PACKET }; + + enum Send_pkt_result { SUCCEEDED, FAILED, PACKET_WAITS_FOR_ARP }; + + Genode::Allocator &_alloc; + Nic_connection_notifier &_notifier; + Net::Dhcp_client _dhcp_client; + Genode::Reconstructible _ip_config; + Nic::Packet_allocator _packet_alloc { &_alloc }; + bool _notify_peers { true }; + Net::Arp_cache _arp_cache { }; + Net::Arp_waiter_list _arp_waiters { }; + Nic::Connection _connection; + Net::Mac_address const _mac_address { _connection.mac_address() }; + bool const _verbose { true }; + bool const _verbose_pkt_drop { true }; + Genode::Signal_handler _link_state_handler; + + Send_pkt_result + _finish_send_eth_ipv4_with_eth_dst_set_via_arp(Nic::Packet_descriptor pkt, + Net::Mac_address const ð_dst); + + void _connection_tx_flush_acks(); + + template + Send_pkt_result + _send_eth_ipv4_with_eth_dst_set_via_arp(Genode::size_t pkt_size, + Net::Ipv4_address const &dst_ip, + FUNC && write_to_pkt) + { + Send_pkt_result result { Send_pkt_result::FAILED }; + try { + Nic::Packet_descriptor pkt { _connection.tx()->alloc_packet(pkt_size) }; + void *pkt_base { _connection.tx()->packet_content(pkt) }; + Net::Size_guard size_guard { pkt_size }; + Net::Ethernet_frame ð { Net::Ethernet_frame::construct_at(pkt_base, size_guard) }; + + write_to_pkt(eth, size_guard); + _arp_cache.find_by_ip(dst_ip).with_result( + [&] (Net::Const_pointer entry_ref) { + result = _finish_send_eth_ipv4_with_eth_dst_set_via_arp( + pkt, entry_ref.deref().mac()); + }, + [&] (Net::Arp_cache_error) { + _broadcast_arp_request(ip_config().interface().address, dst_ip); + new (_alloc) Net::Arp_waiter { _arp_waiters, dst_ip, pkt }; + result = Send_pkt_result::PACKET_WAITS_FOR_ARP; + } + ); + } + catch (Packet_source::Packet_alloc_failed) { + if (_verbose) { + Genode::log("Failed sending NIC packet - Failed allocating packet"); + } + } + return result; + } + + Handle_pkt_result _drop_pkt(char const *packet_type, + char const *reason); + + Send_pkt_result _send_arp_reply(Net::Ethernet_frame &request_eth, + Net::Arp_packet &request_arp); + + Handle_pkt_result _handle_arp_request(Net::Ethernet_frame ð, + Net::Arp_packet &arp); + + Handle_pkt_result _handle_arp(Net::Ethernet_frame ð, + Net::Size_guard &size_guard); + + void _broadcast_arp_request(Net::Ipv4_address const &src_ip, + Net::Ipv4_address const &dst_ip); + + Handle_pkt_result _handle_arp_reply(Net::Arp_packet &arp); + + void _handle_link_state(); + + public: + + Nic_connection(Genode::Env &env, + Genode::Allocator &heap, + Genode::Signal_context_capability pkt_stream_sigh, + Genode::Xml_node const &config_node, + Timer::Connection &timer, + Nic_connection_notifier ¬ifier); + + void for_each_rx_packet(Handle_packet_func handle_packet); + + void notify_peer(); + + void send_wg_prot(Genode::uint8_t const *wg_prot_base, + Genode::size_t wg_prot_size, + Genode::uint16_t udp_src_port_big_endian, + Genode::uint16_t udp_dst_port_big_endian, + Genode::uint32_t ipv4_src_addr_big_endian, + Genode::uint32_t ipv4_dst_addr_big_endian, + Genode::uint8_t ipv4_dscp_ecn, + Genode::uint8_t ipv4_ttl); + + Genode::Microseconds dhcp_discover_timeout() const { return Genode::Microseconds { 3 * 1000 * 1000 }; } + + Genode::Microseconds dhcp_request_timeout() const { return Genode::Microseconds { 10 * 1000 * 1000 }; } + + Ipv4_config const &ip_config() const { return *_ip_config; } + + bool verbose() const { return _verbose; } + + void discard_ip_config(); + + void ip_config_from_dhcp_ack(Net::Dhcp_packet &dhcp_ack); + + Net::Mac_address mac_address() const { return _mac_address; } + + template + Send_pkt_result send(Genode::size_t pkt_size, FUNC && write_to_pkt) + { + try { + Nic::Packet_descriptor pkt { _connection.tx()->alloc_packet(pkt_size) }; + void *pkt_base { _connection.tx()->packet_content(pkt) }; + Net::Size_guard size_guard { pkt_size }; + + write_to_pkt(pkt_base, size_guard); + _connection_tx_flush_acks(); + _connection.tx()->submit_packet(pkt); + } + catch (Packet_source::Packet_alloc_failed) { + if (_verbose) { + Genode::log("Failed sending NIC packet - Failed allocating packet"); + } + return Send_pkt_result::FAILED; + } + return Send_pkt_result::SUCCEEDED; + } +}; + +#endif /* _NIC_CONNECTION_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/pointer.h b/repos/dde_linux/src/app/wireguard/pointer.h new file mode 100644 index 0000000000..6db321bbe5 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/pointer.h @@ -0,0 +1,48 @@ +/* + * \brief Pointer that can be dereferenced only when valid + * \author Martin Stein + * \date 2017-03-08 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _POINTER_H_ +#define _POINTER_H_ + +/* Genode includes */ +#include + +namespace Net { template class Const_pointer; } + +template +class Net::Const_pointer +{ + private: + + T const *_ptr { nullptr }; + + public: + + struct Invalid : Genode::Exception { }; + + Const_pointer() { } + + Const_pointer(T const &ref) : _ptr(&ref) { } + + T const &deref() const + { + if (_ptr == nullptr) { + throw Invalid(); + } + return *_ptr; + } + + bool valid() const { return _ptr != nullptr; } +}; + +#endif /* _POINTER_H_ */ diff --git a/repos/dde_linux/src/app/wireguard/random.cc b/repos/dde_linux/src/app/wireguard/random.cc new file mode 100644 index 0000000000..f6e7dd8936 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/random.cc @@ -0,0 +1,36 @@ +/* + * \brief Randomness backend for lx_emul + * \author Stefan Kalkowski + * \date 2022-01-12 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#include +#include +#include +#include + + +extern "C" void lx_emul_random_bytes(void * buf, int bytes) +{ + static rand_data * jent = nullptr; + + if (!jent) { + jitterentropy_init(Lx_kit::env().heap); + + if (jent_entropy_init() != 0) + Genode::error("jitterentropy library could not be initialized!"); + + jent = jent_entropy_collector_alloc(0, 0); + if (!jent) + Genode::error("jitterentropy could not allocate entropy collector!"); + } + + jent_read_entropy(jent, (char*)buf, bytes); +} diff --git a/repos/dde_linux/src/app/wireguard/spec/arm_64/dummies_arch.c b/repos/dde_linux/src/app/wireguard/spec/arm_64/dummies_arch.c new file mode 100644 index 0000000000..db645de314 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/spec/arm_64/dummies_arch.c @@ -0,0 +1,113 @@ +/** + * \brief Architecture-specific dummy definitions of Linux Kernel functions + * \author Martin Stein + * \date 2022-05-09 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include +#include + +unsigned long long sched_clock(void) +{ + return lx_emul_time_counter() * 1000; +} + + +#include + +bool cpu_have_feature(unsigned int num) +{ + return 0; +} + +u64 vabits_actual; + +void rcu_read_unlock_strict(void) +{ + lx_emul_trace(__func__); +} + +unsigned long __must_check __arch_copy_to_user(void __user *to, const void *from, unsigned long n) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void __init unflatten_device_tree(void) +{ + lx_emul_trace(__func__); +} + +#include + +bool __init early_init_dt_scan(void * params) +{ + lx_emul_trace(__func__); + return false; +} + +void __init irqchip_init(void) { + lx_emul_trace(__func__); +} + + +#include + +void __init sched_clock_register(u64 (* read)(void),int bits,unsigned long rate) +{ + lx_emul_trace(__func__); +} + +#include + +void __init of_clk_init(const struct of_device_id * matches) +{ + lx_emul_trace(__func__); +} + + +#include + +void __init generic_sched_clock_init(void) +{ + lx_emul_trace(__func__); +} + +#include + +void do_set_cpus_allowed(struct task_struct * p,const struct cpumask * new_mask) +{ + lx_emul_trace(__func__); +} + + +#include + +void __init of_core_init(void) +{ + lx_emul_trace(__func__); +} + +#include + +int stop_machine(cpu_stop_fn_t fn,void * data,const struct cpumask * cpus) +{ + return (*fn)(data); +} + + +#include + +void kvfree(const void * addr) +{ + lx_emul_trace_and_stop(__func__); +} diff --git a/repos/dde_linux/src/app/wireguard/spec/arm_64/generated_dummies.c b/repos/dde_linux/src/app/wireguard/spec/arm_64/generated_dummies.c new file mode 100644 index 0000000000..56074c7607 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/spec/arm_64/generated_dummies.c @@ -0,0 +1,693 @@ +/* + * \brief Dummy definitions of Linux Kernel functions + * \author Automatically generated file - do no edit + * \date 2022-05-04 + */ + +#include + + +#include + +int ___ratelimit(struct ratelimit_state * rs,const char * func) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct page * __alloc_pages(gfp_t gfp,unsigned int order,int preferred_nid,nodemask_t * nodemask) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const char * __clk_get_name(const struct clk * clk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +unsigned long __get_free_pages(gfp_t gfp_mask,unsigned int order) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void __icmp_send(struct sk_buff * skb_in,int type,int code,__be32 info,const struct ip_options * opt) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int __ipv6_addr_type(const struct in6_addr * addr) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct irq_domain * __irq_domain_add(struct fwnode_handle * fwnode,int size,irq_hw_number_t hwirq_max,int direct_max,const struct irq_domain_ops * ops,void * host_data) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct irq_desc * __irq_resolve_mapping(struct irq_domain * domain,irq_hw_number_t hwirq,unsigned int * irq) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void __netif_napi_del(struct napi_struct * napi) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +unsigned long __per_cpu_offset[NR_CPUS] = {}; + + +#include + +void __put_page(struct page * page) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void __put_task_struct(struct task_struct * tsk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct sk_buff * __skb_gso_segment(struct sk_buff * skb,netdev_features_t features,bool tx_path) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const unsigned char _ctype[] = {}; + + +#include + +atomic_long_t _totalram_pages; + + +#include + +int crypto_register_shash(struct shash_alg * alg) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct net_device * dev_get_by_index(struct net * net,int ifindex) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void dev_get_tstats64(struct net_device * dev,struct rtnl_link_stats64 * s) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +asmlinkage __visible void dump_stack(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +extern void flush_dcache_page(struct page * page); +void flush_dcache_page(struct page * page) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void free_netdev(struct net_device * dev) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void free_pages(unsigned long addr,unsigned int order) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void free_uid(struct user_struct * up) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +unsigned int fwnode_count_parents(const struct fwnode_handle * fwnode) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const char * fwnode_get_name(const struct fwnode_handle * fwnode) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const char * fwnode_get_name_prefix(const struct fwnode_handle * fwnode) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct fwnode_handle * fwnode_get_nth_parent(struct fwnode_handle * fwnode,unsigned int depth) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void fwnode_handle_put(struct fwnode_handle * fwnode) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void * genlmsg_put(struct sk_buff * skb,u32 portid,u32 seq,const struct genl_family * family,int flags,u8 cmd) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool gfp_pfmemalloc_allowed(gfp_t gfp_mask) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const u8 guid_index[16] = {}; + + +#include + +void handle_fasteoi_irq(struct irq_desc * desc) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const char hex_asc[] = {}; + + +#include + +const char hex_asc_upper[] = {}; + + +#include + +void icmp6_send(struct sk_buff * skb,u8 type,u8 code,__u32 info,const struct in6_addr * force_saddr,const struct inet6_skb_parm * parm) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const struct in6_addr in6addr_any; + + +#include + +struct net init_net; + + +#include + +void io_schedule_finish(int token) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int io_schedule_prepare(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +long __sched io_schedule_timeout(long timeout) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int ip6_dst_hoplimit(struct dst_entry * dst) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const struct header_ops ip_tunnel_header_ops; + + +#include + +int ipv6_chk_addr(struct net * net,const struct in6_addr * addr,const struct net_device * dev,int strict) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int irq_can_set_affinity(unsigned int irq) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void irq_domain_free_irqs_common(struct irq_domain * domain,unsigned int virq,unsigned int nr_irqs) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void irq_domain_set_info(struct irq_domain * domain,unsigned int virq,irq_hw_number_t hwirq,struct irq_chip * chip,void * chip_data,irq_flow_handler_t handler,void * handler_data,const char * handler_name) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void irq_modify_status(unsigned int irq,unsigned long clr,unsigned long set) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int irq_set_affinity(unsigned int irq,const struct cpumask * cpumask) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void irq_set_default_host(struct irq_domain * domain) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct irq_desc * irq_to_desc(unsigned int irq) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void irq_work_tick(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +unsigned long volatile __cacheline_aligned_in_smp __jiffy_arch_data jiffies; + + +#include + +int kmem_cache_alloc_bulk(struct kmem_cache * s,gfp_t flags,size_t size,void ** p) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void kmem_cache_destroy(struct kmem_cache * s) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int kstrtoll(const char * s,unsigned int base,long long * res) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +unsigned long lpj_fine; + + +#include + +void migrate_disable(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void migrate_enable(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void napi_disable(struct napi_struct * n) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void netif_carrier_off(struct net_device * dev) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct property * of_find_property(const struct device_node * np,const char * name,int * lenp) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const struct fwnode_operations of_fwnode_ops; + + +#include + +const char * of_prop_next_string(struct property * prop,const char * cur) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int of_property_read_string(const struct device_node * np,const char * propname,const char ** out_string) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool osq_lock(struct optimistic_spin_queue * lock) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void osq_unlock(struct optimistic_spin_queue * lock) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void page_frag_free(void * addr) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void percpu_counter_add_batch(struct percpu_counter * fbc,s64 amount,s32 batch) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int printk_deferred(const char * fmt,...) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void queued_read_lock_slowpath(struct qrwlock * lock) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void queued_spin_lock_slowpath(struct qspinlock * lock,u32 val) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void queued_write_lock_slowpath(struct qrwlock * lock) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void rtnl_link_unregister(struct rtnl_link_ops * ops) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void sk_clear_memalloc(struct sock * sk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void sk_error_report(struct sock * sk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void sk_free(struct sock * sk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int skb_checksum_help(struct sk_buff * skb) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void skb_set_owner_w(struct sk_buff * skb,struct sock * sk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void sock_edemux(struct sk_buff * skb) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool static_key_initialized; + + +#include + +int string_escape_mem(const char * src,size_t isz,char * dst,size_t osz,unsigned int flags,const char * only) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void tick_broadcast(const struct cpumask * mask) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool timerqueue_add(struct timerqueue_head * head,struct timerqueue_node * node) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool timerqueue_del(struct timerqueue_head * head,struct timerqueue_node * node) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct timerqueue_node * timerqueue_iterate_next(struct timerqueue_node * node) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int udp_sock_create6(struct net * net,struct udp_port_cfg * cfg,struct socket ** sockp) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int udp_tunnel6_xmit_skb(struct dst_entry * dst,struct sock * sk,struct sk_buff * skb,struct net_device * dev,struct in6_addr * saddr,struct in6_addr * daddr,__u8 prio,__u8 ttl,__be32 label,__be16 src_port,__be16 dst_port,bool nocheck) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void udp_tunnel_sock_release(struct socket * sock) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void unregister_pernet_device(struct pernet_operations * ops) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const u8 uuid_index[16] = {}; + + +#include + +void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task) +{ + lx_emul_trace_and_stop(__func__); +} + diff --git a/repos/dde_linux/src/app/wireguard/spec/arm_64/genode_c_api_arch.c b/repos/dde_linux/src/app/wireguard/spec/arm_64/genode_c_api_arch.c new file mode 100644 index 0000000000..533e6f70e2 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/spec/arm_64/genode_c_api_arch.c @@ -0,0 +1,17 @@ + +#include + +void genode_wg_arch_net_dev_init(struct net_device *net_dev, + int *pcpu_refcnt) +{ + net_dev->pcpu_refcnt = pcpu_refcnt; +} + + +void finalize_system_capabilities(void); + + +void genode_wg_arch_lx_user_init(void) +{ + finalize_system_capabilities(); +} diff --git a/repos/dde_linux/src/app/wireguard/spec/arm_64/lx_emul/initcall_order.h b/repos/dde_linux/src/app/wireguard/spec/arm_64/lx_emul/initcall_order.h new file mode 100644 index 0000000000..089d1d39b1 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/spec/arm_64/lx_emul/initcall_order.h @@ -0,0 +1,159 @@ +/* + * \brief Array defining order of Linux Kernel initcalls + * \author Automatically generated file - do no edit + * \date 2022-05-05 + */ + +#pragma once + +static const char * lx_emul_initcall_order[] = { + "__initcall_asids_initearly", + "__initcall_start", + "__initcall_spawn_ksoftirqdearly", + "__initcall_migration_initearly", + "__initcall_srcu_bootup_announceearly", + "__initcall_rcu_spawn_gp_kthreadearly", + "__initcall_check_cpu_stall_initearly", + "__initcall_rcu_sysrq_initearly", + "__initcall_cpu_stop_initearly", + "__initcall_init_zero_pfnearly", + "__initcall_its_pmsi_initearly", + "__initcall_its_pci_msi_initearly", + "__initcall_dummy_timer_registerearly", + "__initcall_initialize_ptr_randomearly", + "__initcall_init_mmap_min_addr0", + "__initcall_pci_realloc_setup_params0", + "__initcall_net_ns_init0", + "__initcall_inet_frag_wq_init0", + "__initcall_fpsimd_init1", + "__initcall_enable_mrs_emulation1", + "__initcall_init_amu_fie1", + "__initcall_ksysfs_init1", + "__initcall_rcu_set_runtime_mode1", + "__initcall_dma_init_reserved_memory1", + "__initcall_init_jiffies_clocksource1", + "__initcall_init_elf_binfmt1", + "__initcall_prandom_init_early1", + "__initcall_virtio_init1", + "__initcall_free_raw_capacity1", + "__initcall_sock_init1", + "__initcall_net_defaults_init1", + "__initcall_init_default_flow_dissectors1", + "__initcall_netlink_proto_init1", + "__initcall_genl_init1", + "__initcall_debug_monitors_init2", + "__initcall_dma_atomic_pool_init2", + "__initcall_bdi_class_init2", + "__initcall_mm_sysfs_init2", + "__initcall_init_per_zone_wmark_min2", + "__initcall_pcibus_class_init2", + "__initcall_pci_driver_init2", + "__initcall_amba_init2", + "__initcall_tty_class_init2", + "__initcall_vtconsole_class_init2", + "__initcall_devlink_class_init2", + "__initcall_software_node_init2", + "__initcall_kobject_uevent_init2", + "__initcall_reserve_memblock_reserved_regions3", + "__initcall_vdso_init3", + "__initcall_asids_update_limit3", + "__initcall_of_platform_default_populate_init3s", + "__initcall_topology_init4", + "__initcall_uid_cache_init4", + "__initcall_user_namespace_sysctl_init4", + "__initcall_oom_init4", + "__initcall_default_bdi_init4", + "__initcall_percpu_enable_async4", + "__initcall_init_user_reserve4", + "__initcall_init_admin_reserve4", + "__initcall_init_reserve_notifier4", + "__initcall_aes_init4", + "__initcall_prng_mod_init4", + "__initcall_misc_init4", + "__initcall_register_cpu_capacity_sysctl4", + "__initcall_input_init4", + "__initcall_power_supply_class_init4", + "__initcall_net_dev_init4", + "__initcall_neigh_init4", + "__initcall_fib_notifier_init4", + "__initcall_ethnl_init4", + "__initcall_nexthop_init4", + "__initcall_init_32bit_el0_mask4s", + "__initcall_create_debug_debugfs_entry5", + "__initcall_iomem_init_inode5", + "__initcall_clocksource_done_booting5", + "__initcall_init_pipe_fs5", + "__initcall_anon_inode_init5", + "__initcall_init_ramfs_fs5", + "__initcall_chr_dev_init5", + "__initcall_eth_offload_init5", + "__initcall_ipv4_offload_init5", + "__initcall_inet_init5", + "__initcall_ipv6_offload_init5", + "__initcall_pci_apply_final_quirks5s", + "__initcall_populate_rootfsrootfs", + "__initcall_register_arm64_panic_block6", + "__initcall_cpuinfo_regs_init6", + "__initcall_chacha_simd_mod_init6", + "__initcall_neon_poly1305_mod_init6", + "__initcall_timekeeping_init_ops6", + "__initcall_alarmtimer_init6", + "__initcall_sched_clock_syscore_init6", + "__initcall_kswapd_init6", + "__initcall_mm_compute_batch_init6", + "__initcall_workingset_init6", + "__initcall_fcntl_init6", + "__initcall_start_dirtytime_writeback6", + "__initcall_init_devpts_fs6", + "__initcall_crypto_algapi_init6", + "__initcall_jent_mod_init6", + "__initcall_mod_init6", + "__initcall_mod_init6", + "__initcall_mod_init6", + "__initcall_percpu_counter_startup6", + "__initcall_of_fixed_factor_clk_driver_init6", + "__initcall_of_fixed_clk_driver_init6", + "__initcall_gpio_clk_driver_init6", + "__initcall_virtio_pci_driver_init6", + "__initcall_n_null_init6", + "__initcall_pty_init6", + "__initcall_init6", + "__initcall_hwrng_modinit6", + "__initcall_timeriomem_rng_driver_init6", + "__initcall_cavium_rng_pf_driver_init6", + "__initcall_cavium_rng_vf_driver_init6", + "__initcall_topology_sysfs_init6", + "__initcall_cacheinfo_sysfs_init6", + "__initcall_mod_init6", + "__initcall_net_olddevs_init6", + "__initcall_blackhole_netdev_init6", + "__initcall_virtio_net_driver_init6", + "__initcall_net_failover_init6", + "__initcall_sock_diag_init6", + "__initcall_failover_init6", + "__initcall_gre_offload_init6", + "__initcall_tunnel4_init6", + "__initcall_inet_diag_init6", + "__initcall_tcp_diag_init6", + "__initcall_cubictcp_register6", + "__initcall_inet6_init6", + "__initcall_sit_init6", + "__initcall_init_oops_id7", + "__initcall_printk_late_init7", + "__initcall_check_early_ioremap_leak7", + "__initcall_prandom_init_late7", + "__initcall_pci_resource_alignment_sysfs_init7", + "__initcall_pci_sysfs_init7", + "__initcall_amba_deferred_retry7", + "__initcall_sync_state_resume_initcall7", + "__initcall_deferred_probe_initcall7", + "__initcall_tcp_congestion_default7", + "__initcall_udp_tunnel_nic_init_module7", + "__initcall_ip_auto_config7", + "__initcall_clk_disable_unused7s", + "__initcall_of_platform_sync_state_init7s", + "__initcall_con_initcon", + "__initcall_end", + "__initcall_hvc_console_initcon", + "END_OF_INITCALL_ORDER_ARRAY_DUMMY_ENTRY" +}; diff --git a/repos/dde_linux/src/app/wireguard/spec/arm_64/source.list b/repos/dde_linux/src/app/wireguard/spec/arm_64/source.list new file mode 100644 index 0000000000..ab9a46de1e --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/spec/arm_64/source.list @@ -0,0 +1,71 @@ +arch/arm64/crypto/poly1305-glue.c +arch/arm64/crypto/chacha-neon-glue.c +arch/arm64/lib/memcmp.S +arch/arm64/lib/memchr.S +arch/arm64/lib/strcmp.S +arch/arm64/lib/strlen.S +crypto/skcipher.c +crypto/api.c +lib/hweight.c +lib/cpumask.c +crypto/algapi.c +crypto/memneq.c +crypto/scatterwalk.c +drivers/net/wireguard/allowedips.c +drivers/net/wireguard/cookie.c +drivers/net/wireguard/device.c +drivers/net/wireguard/main.c +drivers/net/wireguard/netlink.c +drivers/net/wireguard/noise.c +drivers/net/wireguard/peer.c +drivers/net/wireguard/peerlookup.c +drivers/net/wireguard/queueing.c +drivers/net/wireguard/ratelimiter.c +drivers/net/wireguard/receive.c +drivers/net/wireguard/send.c +drivers/net/wireguard/socket.c +drivers/net/wireguard/timers.c +kernel/kthread.c +kernel/locking/mutex.c +kernel/locking/rwsem.c +kernel/notifier.c +kernel/sched/clock.c +kernel/sched/completion.c +kernel/sched/swait.c +kernel/sched/wait.c +kernel/time/clockevents.c +kernel/time/clocksource.c +kernel/time/hrtimer.c +kernel/time/jiffies.c +kernel/time/ntp.c +kernel/time/tick-broadcast.c +kernel/time/tick-common.c +kernel/time/time.c +kernel/time/timeconv.c +kernel/time/timecounter.c +kernel/time/timekeeping.c +kernel/time/timer.c +kernel/time/timer_list.c +kernel/workqueue.c +lib/bitmap.c +lib/crypto/blake2s-generic.c +lib/crypto/blake2s.c +lib/crypto/chacha.c +lib/crypto/chacha20poly1305.c +lib/crypto/curve25519-generic.c +lib/crypto/curve25519-hacl64.c +lib/crypto/libchacha.c +lib/find_bit.c +lib/idr.c +lib/nlattr.c +lib/radix-tree.c +lib/refcount.c +lib/scatterlist.c +lib/siphash.c +lib/string.c +lib/vsprintf.c +lib/xarray.c +net/core/dst.c +net/core/dst_cache.c +net/core/flow_dissector.c +net/core/skbuff.c diff --git a/repos/dde_linux/src/app/wireguard/spec/arm_64/target.mk b/repos/dde_linux/src/app/wireguard/spec/arm_64/target.mk new file mode 100644 index 0000000000..b14582fb21 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/spec/arm_64/target.mk @@ -0,0 +1,5 @@ +REQUIRES = arm_64 + +INC_DIR += $(REP_DIR)/src/include/spec/arm_64 + +include $(PRG_DIR)/../../target.inc diff --git a/repos/dde_linux/src/app/wireguard/spec/x86_64/dummies_arch.c b/repos/dde_linux/src/app/wireguard/spec/x86_64/dummies_arch.c new file mode 100644 index 0000000000..701702b0b8 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/spec/x86_64/dummies_arch.c @@ -0,0 +1,26 @@ +/** + * \brief Architecture-specific dummy definitions of Linux Kernel functions + * \author Stefan Kalkowski + * \author Martin Stein + * \date 2022-05-09 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +#include + + +#include + +void clocksource_arch_init(struct clocksource * cs) +{ + lx_emul_trace(__func__); +} + + +struct cpuinfo_x86 boot_cpu_data __read_mostly; diff --git a/repos/dde_linux/src/app/wireguard/spec/x86_64/generated_dummies.c b/repos/dde_linux/src/app/wireguard/spec/x86_64/generated_dummies.c new file mode 100644 index 0000000000..66bdcc1066 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/spec/x86_64/generated_dummies.c @@ -0,0 +1,596 @@ +/* + * \brief Dummy definitions of Linux Kernel functions + * \author Automatically generated file - do no edit + * \date 2022-01-25 + */ + +#include + + +#include + +int ___ratelimit(struct ratelimit_state * rs,const char * func) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct page * __alloc_pages(gfp_t gfp,unsigned int order,int preferred_nid,nodemask_t * nodemask) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const char * __clk_get_name(const struct clk * clk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void __icmp_send(struct sk_buff * skb_in,int type,int code,__be32 info,const struct ip_options * opt) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int __ipv6_addr_type(const struct in6_addr * addr) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct irq_domain * __irq_domain_add(struct fwnode_handle * fwnode,int size,irq_hw_number_t hwirq_max,int direct_max,const struct irq_domain_ops * ops,void * host_data) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct irq_desc * __irq_resolve_mapping(struct irq_domain * domain,irq_hw_number_t hwirq,unsigned int * irq) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void __netif_napi_del(struct napi_struct * napi) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void __put_page(struct page * page) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void __put_task_struct(struct task_struct * tsk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct sk_buff * __skb_gso_segment(struct sk_buff * skb,netdev_features_t features,bool tx_path) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +unsigned long _copy_to_user(void __user * to,const void * from,unsigned long n) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const unsigned char _ctype[] = {}; + + +extern const char * _parse_integer_fixup_radix(const char * s,unsigned int * base); +const char * _parse_integer_fixup_radix(const char * s,unsigned int * base) +{ + lx_emul_trace_and_stop(__func__); +} + + +extern unsigned int _parse_integer_limit(const char * s,unsigned int base,unsigned long long * p,size_t max_chars); +unsigned int _parse_integer_limit(const char * s,unsigned int base,unsigned long long * p,size_t max_chars) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +atomic_long_t _totalram_pages; + + +extern void ack_bad_irq(unsigned int irq); +void ack_bad_irq(unsigned int irq) +{ + lx_emul_trace_and_stop(__func__); +} + + +extern int cpu_has_xfeatures(u64 xfeatures_needed,const char ** feature_name); +int cpu_has_xfeatures(u64 xfeatures_needed,const char ** feature_name) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int crypto_register_skciphers(struct skcipher_alg * algs,int count) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct net_device * dev_get_by_index(struct net * net,int ifindex) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void dev_get_tstats64(struct net_device * dev,struct rtnl_link_stats64 * s) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +asmlinkage __visible void dump_stack(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void free_netdev(struct net_device * dev) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void free_uid(struct user_struct * up) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +unsigned int fwnode_count_parents(const struct fwnode_handle * fwnode) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const char * fwnode_get_name(const struct fwnode_handle * fwnode) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const char * fwnode_get_name_prefix(const struct fwnode_handle * fwnode) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct fwnode_handle * fwnode_get_nth_parent(struct fwnode_handle * fwnode,unsigned int depth) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void fwnode_handle_put(struct fwnode_handle * fwnode) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void * genlmsg_put(struct sk_buff * skb,u32 portid,u32 seq,const struct genl_family * family,int flags,u8 cmd) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool gfp_pfmemalloc_allowed(gfp_t gfp_mask) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const u8 guid_index[16] = {}; + + +#include + +const char hex_asc[] = {}; + + +#include + +const char hex_asc_upper[] = {}; + + +#include + +void icmp6_send(struct sk_buff * skb,u8 type,u8 code,__u32 info,const struct in6_addr * force_saddr,const struct inet6_skb_parm * parm) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const struct in6_addr in6addr_any; + + +#include + +struct net init_net; + + +#include + +void io_schedule_finish(int token) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int io_schedule_prepare(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +long __sched io_schedule_timeout(long timeout) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int ip6_dst_hoplimit(struct dst_entry * dst) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const struct header_ops ip_tunnel_header_ops; + + +#include + +int ipv6_chk_addr(struct net * net,const struct in6_addr * addr,const struct net_device * dev,int strict) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void irq_domain_free_irqs_common(struct irq_domain * domain,unsigned int virq,unsigned int nr_irqs) +{ + lx_emul_trace_and_stop(__func__); +} + + +extern bool irq_fpu_usable(void); +bool irq_fpu_usable(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void irq_set_default_host(struct irq_domain * domain) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void irq_work_tick(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +unsigned long volatile __cacheline_aligned_in_smp __jiffy_arch_data jiffies; + + +extern void kernel_fpu_begin_mask(unsigned int kfpu_mask); +void kernel_fpu_begin_mask(unsigned int kfpu_mask) +{ + lx_emul_trace_and_stop(__func__); +} + + +extern void kernel_fpu_end(void); +void kernel_fpu_end(void) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int kmem_cache_alloc_bulk(struct kmem_cache * s,gfp_t flags,size_t size,void ** p) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void kmem_cache_destroy(struct kmem_cache * s) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int kstrtoll(const char * s,unsigned int base,long long * res) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void kvfree(const void * addr) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +unsigned long lpj_fine; + + +#include + +void napi_disable(struct napi_struct * n) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void netif_carrier_off(struct net_device * dev) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void page_frag_free(void * addr) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int printk_deferred(const char * fmt,...) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void rtnl_link_unregister(struct rtnl_link_ops * ops) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void sk_clear_memalloc(struct sock * sk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void sk_error_report(struct sock * sk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void sk_free(struct sock * sk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int skb_checksum_help(struct sk_buff * skb) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void skb_set_owner_w(struct sk_buff * skb,struct sock * sk) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int skcipher_walk_done(struct skcipher_walk * walk,int err) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int skcipher_walk_virt(struct skcipher_walk * walk,struct skcipher_request * req,bool atomic) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void sock_edemux(struct sk_buff * skb) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool static_key_initialized; + + +#include + +int string_escape_mem(const char * src,size_t isz,char * dst,size_t osz,unsigned int flags,const char * only) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool timerqueue_add(struct timerqueue_head * head,struct timerqueue_node * node) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +bool timerqueue_del(struct timerqueue_head * head,struct timerqueue_node * node) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +struct timerqueue_node * timerqueue_iterate_next(struct timerqueue_node * node) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int udp_sock_create6(struct net * net,struct udp_port_cfg * cfg,struct socket ** sockp) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +int udp_tunnel6_xmit_skb(struct dst_entry * dst,struct sock * sk,struct sk_buff * skb,struct net_device * dev,struct in6_addr * saddr,struct in6_addr * daddr,__u8 prio,__u8 ttl,__be32 label,__be16 src_port,__be16 dst_port,bool nocheck) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void udp_tunnel_sock_release(struct socket * sock) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +void unregister_pernet_device(struct pernet_operations * ops) +{ + lx_emul_trace_and_stop(__func__); +} + + +#include + +const u8 uuid_index[16] = {}; + + +#include + +void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task) +{ + lx_emul_trace_and_stop(__func__); +} diff --git a/repos/dde_linux/src/app/wireguard/spec/x86_64/genode_c_api_arch.c b/repos/dde_linux/src/app/wireguard/spec/x86_64/genode_c_api_arch.c new file mode 100644 index 0000000000..355baaa7f6 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/spec/x86_64/genode_c_api_arch.c @@ -0,0 +1,11 @@ + +#include + +void genode_wg_arch_net_dev_init(struct net_device *net_dev, + int *pcpu_refcnt) +{ +} + +void genode_wg_arch_lx_user_init(void) +{ +} diff --git a/repos/dde_linux/src/app/wireguard/spec/x86_64/lx_emul/initcall_order.h b/repos/dde_linux/src/app/wireguard/spec/x86_64/lx_emul/initcall_order.h new file mode 100644 index 0000000000..b275b472e0 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/spec/x86_64/lx_emul/initcall_order.h @@ -0,0 +1,188 @@ +/* + * \brief Array defining order of Linux Kernel initcalls + * \author Automatically generated file - do no edit + * \date 2022-01-06 + */ + +#pragma once + +static const char * lx_emul_initcall_order[] = { + "__initcall_init_hw_perf_eventsearly", + "__initcall_start", + "__initcall_init_real_modeearly", + "__initcall_validate_x2apicearly", + "__initcall_register_nmi_cpu_backtrace_handlerearly", + "__initcall_spawn_ksoftirqdearly", + "__initcall_static_call_initearly", + "__initcall_init_zero_pfnearly", + "__initcall_initialize_ptr_randomearly", + "__initcall_init_mmap_min_addr0", + "__initcall_pci_realloc_setup_params0", + "__initcall_net_ns_init0", + "__initcall_inet_frag_wq_init0", + "__initcall_reboot_init1", + "__initcall_ksysfs_init1", + "__initcall_rcu_set_runtime_mode1", + "__initcall_init_jiffies_clocksource1", + "__initcall_init_elf_binfmt1", + "__initcall_prandom_init_early1", + "__initcall_sock_init1", + "__initcall_net_defaults_init1", + "__initcall_init_default_flow_dissectors1", + "__initcall_netlink_proto_init1", + "__initcall_genl_init1", + "__initcall_bdi_class_init2", + "__initcall_mm_sysfs_init2", + "__initcall_init_per_zone_wmark_min2", + "__initcall_pcibus_class_init2", + "__initcall_pci_driver_init2", + "__initcall_tty_class_init2", + "__initcall_vtconsole_class_init2", + "__initcall_devlink_class_init2", + "__initcall_software_node_init2", + "__initcall_i2c_init2", + "__initcall_amd_postcore_init2", + "__initcall_kobject_uevent_init2", + "__initcall_bts_init3", + "__initcall_pt_init3", + "__initcall_sbf_init3", + "__initcall_arch_kdebugfs_init3", + "__initcall_intel_pconfig_init3", + "__initcall_pci_arch_init3", + "__initcall_init_vdso4", + "__initcall_fixup_ht_bug4", + "__initcall_topology_init4", + "__initcall_uid_cache_init4", + "__initcall_user_namespace_sysctl_init4", + "__initcall_oom_init4", + "__initcall_default_bdi_init4", + "__initcall_percpu_enable_async4", + "__initcall_init_user_reserve4", + "__initcall_init_admin_reserve4", + "__initcall_init_reserve_notifier4", + "__initcall_aes_init4", + "__initcall_prng_mod_init4", + "__initcall_misc_init4", + "__initcall_vga_arb_device_init4", + "__initcall_phy_init4", + "__initcall_serio_init4", + "__initcall_input_init4", + "__initcall_net_dev_init4", + "__initcall_neigh_init4", + "__initcall_fib_notifier_init4", + "__initcall_ethnl_init4", + "__initcall_nexthop_init4", + "__initcall_pci_subsys_init4", + "__initcall_nmi_warning_debugfs5", + "__initcall_hpet_late_init5", + "__initcall_init_amd_nbs5", + "__initcall_iomem_init_inode5", + "__initcall_clocksource_done_booting5", + "__initcall_init_pipe_fs5", + "__initcall_anon_inode_init5", + "__initcall_init_ramfs_fs5", + "__initcall_chr_dev_init5", + "__initcall_eth_offload_init5", + "__initcall_ipv4_offload_init5", + "__initcall_inet_init5", + "__initcall_ipv6_offload_init5", + "__initcall_pcibios_assign_resources5", + "__initcall_pci_apply_final_quirks5s", + "__initcall_populate_rootfsrootfs", + "__initcall_pci_iommu_initrootfs", + "__initcall_rapl_pmu_init6", + "__initcall_amd_uncore_init6", + "__initcall_amd_ibs_init6", + "__initcall_msr_init6", + "__initcall_intel_uncore_init6", + "__initcall_cstate_pmu_init6", + "__initcall_register_kernel_offset_dumper6", + "__initcall_i8259A_init_ops6", + "__initcall_init_tsc_clocksource6", + "__initcall_add_rtc_cmos6", + "__initcall_umwait_init6", + "__initcall_ioapic_init_ops6", + "__initcall_sysfb_init6", + "__initcall_chacha_simd_mod_init6", + "__initcall_blake2s_mod_init6", + "__initcall_poly1305_simd_mod_init6", + "__initcall_curve25519_mod_init6", + "__initcall_timekeeping_init_ops6", + "__initcall_alarmtimer_init6", + "__initcall_perf_event_sysfs_init6", + "__initcall_kswapd_init6", + "__initcall_workingset_init6", + "__initcall_fcntl_init6", + "__initcall_start_dirtytime_writeback6", + "__initcall_init_devpts_fs6", + "__initcall_crypto_algapi_init6", + "__initcall_jent_mod_init6", + "__initcall_mod_init6", + "__initcall_mod_init6", + "__initcall_mod_init6", + "__initcall_gpio_clk_driver_init6", + "__initcall_plt_clk_driver_init6", + "__initcall_n_null_init6", + "__initcall_pty_init6", + "__initcall_serial8250_init6", + "__initcall_serial_pci_driver_init6", + "__initcall_exar_pci_driver_init6", + "__initcall_dw8250_platform_driver_init6", + "__initcall_lpss8250_pci_driver_init6", + "__initcall_mid8250_pci_driver_init6", + "__initcall_hwrng_modinit6", + "__initcall_timeriomem_rng_driver_init6", + "__initcall_mod_init6", + "__initcall_mod_init6", + "__initcall_mod_init6", + "__initcall_topology_sysfs_init6", + "__initcall_cacheinfo_sysfs_init6", + "__initcall_mod_init6", + "__initcall_net_olddevs_init6", + "__initcall_blackhole_netdev_init6", + "__initcall_e100_init_module6", + "__initcall_e1000_init_module6", + "__initcall_e1000_init_module6", + "__initcall_igb_init_module6", + "__initcall_igc_init_module6", + "__initcall_igbvf_init_module6", + "__initcall_ixgbe_init_module6", + "__initcall_i40e_init_module6", + "__initcall_ixgb_init_module6", + "__initcall_i8042_init6", + "__initcall_serport_init6", + "__initcall_atkbd_init6", + "__initcall_psmouse_init6", + "__initcall_hid_init6", + "__initcall_hid_generic_init6", + "__initcall_pmc_atom_init6", + "__initcall_sock_diag_init6", + "__initcall_gre_offload_init6", + "__initcall_tunnel4_init6", + "__initcall_inet_diag_init6", + "__initcall_tcp_diag_init6", + "__initcall_cubictcp_register6", + "__initcall_inet6_init6", + "__initcall_sit_init6", + "__initcall_update_mp_table7", + "__initcall_lapic_insert_resource7", + "__initcall_print_ICs7", + "__initcall_create_tlb_single_page_flush_ceiling7", + "__initcall_init_oops_id7", + "__initcall_sched_clock_init_late7", + "__initcall_printk_late_init7", + "__initcall_check_early_ioremap_leak7", + "__initcall_prandom_init_late7", + "__initcall_pci_resource_alignment_sysfs_init7", + "__initcall_pci_sysfs_init7", + "__initcall_sync_state_resume_initcall7", + "__initcall_deferred_probe_initcall7", + "__initcall_tcp_congestion_default7", + "__initcall_udp_tunnel_nic_init_module7", + "__initcall_ip_auto_config7", + "__initcall_clk_disable_unused7s", + "__initcall_con_initcon", + "__initcall_end", + "__initcall_univ8250_console_initcon", + "END_OF_INITCALL_ORDER_ARRAY_DUMMY_ENTRY" +}; diff --git a/repos/dde_linux/src/app/wireguard/spec/x86_64/source.list b/repos/dde_linux/src/app/wireguard/spec/x86_64/source.list new file mode 100644 index 0000000000..4c769c642d --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/spec/x86_64/source.list @@ -0,0 +1,71 @@ +arch/x86/crypto/blake2s-core.S +arch/x86/crypto/blake2s-glue.c +arch/x86/crypto/chacha-avx2-x86_64.S +arch/x86/crypto/chacha-avx512vl-x86_64.S +arch/x86/crypto/chacha-ssse3-x86_64.S +arch/x86/crypto/chacha_glue.c +arch/x86/crypto/curve25519-x86_64.c +arch/x86/crypto/poly1305-x86_64-cryptogams.pl +arch/x86/crypto/poly1305_glue.c +arch/x86/lib/hweight.S +crypto/algapi.c +crypto/memneq.c +crypto/scatterwalk.c +drivers/net/wireguard/allowedips.c +drivers/net/wireguard/cookie.c +drivers/net/wireguard/device.c +drivers/net/wireguard/main.c +drivers/net/wireguard/netlink.c +drivers/net/wireguard/noise.c +drivers/net/wireguard/peer.c +drivers/net/wireguard/peerlookup.c +drivers/net/wireguard/queueing.c +drivers/net/wireguard/ratelimiter.c +drivers/net/wireguard/receive.c +drivers/net/wireguard/send.c +drivers/net/wireguard/socket.c +drivers/net/wireguard/timers.c +kernel/kthread.c +kernel/locking/mutex.c +kernel/locking/rwsem.c +kernel/notifier.c +kernel/sched/clock.c +kernel/sched/completion.c +kernel/sched/swait.c +kernel/sched/wait.c +kernel/time/clockevents.c +kernel/time/clocksource.c +kernel/time/hrtimer.c +kernel/time/jiffies.c +kernel/time/ntp.c +kernel/time/tick-broadcast.c +kernel/time/tick-common.c +kernel/time/time.c +kernel/time/timeconv.c +kernel/time/timecounter.c +kernel/time/timekeeping.c +kernel/time/timer.c +kernel/time/timer_list.c +kernel/workqueue.c +lib/bitmap.c +lib/crypto/blake2s-generic.c +lib/crypto/blake2s.c +lib/crypto/chacha.c +lib/crypto/chacha20poly1305.c +lib/crypto/curve25519-generic.c +lib/crypto/curve25519-hacl64.c +lib/crypto/libchacha.c +lib/find_bit.c +lib/idr.c +lib/nlattr.c +lib/radix-tree.c +lib/refcount.c +lib/scatterlist.c +lib/siphash.c +lib/string.c +lib/vsprintf.c +lib/xarray.c +net/core/dst.c +net/core/dst_cache.c +net/core/flow_dissector.c +net/core/skbuff.c diff --git a/repos/dde_linux/src/app/wireguard/spec/x86_64/target.mk b/repos/dde_linux/src/app/wireguard/spec/x86_64/target.mk new file mode 100644 index 0000000000..cb62c6eeb2 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/spec/x86_64/target.mk @@ -0,0 +1,5 @@ +REQUIRES = x86_64 + +INC_DIR += $(REP_DIR)/src/include/spec/x86_64 + +include $(PRG_DIR)/../../target.inc diff --git a/repos/dde_linux/src/app/wireguard/target.inc b/repos/dde_linux/src/app/wireguard/target.inc new file mode 100644 index 0000000000..7cf9ebe747 --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/target.inc @@ -0,0 +1,21 @@ +TARGET = wireguard +LIBS += base net jitterentropy wireguard +GEN_DIR := $(PRG_DIR)/../.. +INC_DIR += $(GEN_DIR) +INC_DIR += $(REP_DIR)/src/include +SRC_CC += arp_cache.cc +SRC_CC += arp_waiter.cc +SRC_CC += base64.cc +SRC_CC += config_model.cc +SRC_CC += dhcp_client.cc +SRC_CC += ipv4_address_prefix.cc +SRC_CC += ipv4_config.cc +SRC_CC += irq.cc +SRC_CC += main.cc +SRC_CC += nic_connection.cc +SRC_CC += random.cc +SRC_CC += uplink_connection.cc + +vpath %.cc $(GEN_DIR) + +CC_CXX_WARN_STRICT_CONVERSION = diff --git a/repos/dde_linux/src/app/wireguard/uplink_connection.cc b/repos/dde_linux/src/app/wireguard/uplink_connection.cc new file mode 100644 index 0000000000..267547b0ff --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/uplink_connection.cc @@ -0,0 +1,112 @@ +/* + * \brief Network back-end towards private network (unencrypted user packets) + * \author Stefan Kalkowski + * \author Martin Stein + * \date 2022-01-07 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +/* dde_linux wireguard includes */ +#include + +/* os includes */ +#include + +using namespace Genode; +using namespace Net; +using namespace Wireguard; + + +void Uplink_connection::_connection_tx_flush_acks() +{ + while (_connection.tx()->ack_avail()) { + _connection.tx()->release_packet( + _connection.tx()->get_acked_packet()); + } +} + + +void Uplink_connection::send_ip(void const *ip_base, + size_t ip_size) +{ + Size_guard ip_guard { ip_size }; + Ipv4_packet const &ip { Ipv4_packet::cast_from(ip_base, ip_guard) }; + if (ip.version() != 4) { + log("Drop packet - IP versions other than 4 not supported"); + return; + } + size_t const pkt_size { sizeof(Ethernet_frame) + ip_size }; + + _send(pkt_size, [&] (void *pkt_base, Size_guard &size_guard) + { + /* create ETH header */ + Ethernet_frame ð { + Ethernet_frame::construct_at(pkt_base, size_guard) }; + + eth.src(_mac_address); + eth.dst(Ethernet_frame::broadcast()); + eth.type(Ethernet_frame::Type::IPV4); + + /* add IP packet as payload */ + eth.memcpy_to_data((void *)ip_base, ip_size, size_guard); + }); +} + + +void Uplink_connection::notify_peer() +{ + if (_notify_peers) { + _notify_peers = false; + _connection.rx()->wakeup(); + _connection.tx()->wakeup(); + } +} + + +void Uplink_connection::for_each_rx_packet(Handle_packet_func handle_packet) +{ + typename Uplink::Connection::Rx::Sink & rx_sink = *_connection.rx(); + + for (;;) { + + if (!rx_sink.packet_avail() || !rx_sink.ack_slots_free()) + break; + + Packet_descriptor const packet = rx_sink.peek_packet(); + + bool const packet_valid = rx_sink.packet_valid(packet) + && (packet.offset() >= 0); + + if (packet_valid) { + + void *eth_base { rx_sink.packet_content(packet) }; + + handle_packet(eth_base, packet.size()); + _notify_peers = true; + } + (void)rx_sink.try_get_packet(); + rx_sink.try_ack_packet(packet); + } +} + + + +Uplink_connection::Uplink_connection(Env &env, + Allocator &alloc, + Signal_context_capability sigh) +: + _packet_alloc { &alloc }, + _connection { env, &_packet_alloc, BUF_SIZE, BUF_SIZE, _mac_address, + "uplink_session" } +{ + _connection.rx_channel()->sigh_ready_to_ack(sigh); + _connection.rx_channel()->sigh_packet_avail(sigh); + _connection.tx_channel()->sigh_ack_avail(sigh); + _connection.tx_channel()->sigh_ready_to_submit(sigh); +} diff --git a/repos/dde_linux/src/app/wireguard/uplink_connection.h b/repos/dde_linux/src/app/wireguard/uplink_connection.h new file mode 100644 index 0000000000..ed8891e41b --- /dev/null +++ b/repos/dde_linux/src/app/wireguard/uplink_connection.h @@ -0,0 +1,91 @@ +/* + * \brief Network back-end towards private network (unencrypted user packets) + * \author Stefan Kalkowski + * \author Martin Stein + * \date 2022-01-07 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _UPLINK_CONNECTION_H_ +#define _UPLINK_CONNECTION_H_ + +/* os includes */ +#include +#include +#include + +namespace Wireguard { + + class Uplink_connection; +} + + +class Wireguard::Uplink_connection +{ + private: + + using Handle_packet_func = void (*)(void *buf_base, + Genode::size_t buf_size); + + using Packet_descriptor = Uplink::Packet_descriptor; + using Packet_source = + ::Uplink::Packet_stream_source<::Uplink::Session::Policy>; + + enum { PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE }; + enum { BUF_SIZE = Uplink::Connection::Session::QUEUE_SIZE * PACKET_SIZE }; + + enum class Send_pkt_result { SUCCEEDED, FAILED }; + + Nic::Packet_allocator _packet_alloc; + Net::Mac_address const _mac_address { 2 }; + Uplink::Connection _connection; + bool _notify_peers { true }; + bool const _verbose { true }; + bool const _verbose_pkt_drop { true }; + + void _connection_tx_flush_acks(); + + template + Send_pkt_result _send(Genode::size_t pkt_size, + WRITE_TO_PACKET_FUNC && write_to_pkt) + { + try { + Uplink::Packet_descriptor pkt { _connection.tx()->alloc_packet(pkt_size) }; + void *const pkt_base { _connection.tx()->packet_content(pkt) }; + Net::Size_guard size_guard { pkt_size }; + + write_to_pkt(pkt_base, size_guard); + _connection_tx_flush_acks(); + _connection.tx()->submit_packet(pkt); + } + catch (Packet_source::Packet_alloc_failed) { + if (_verbose) { + Genode::log( + "Failed sending uplink packet - Failed allocating packet"); + } + return Send_pkt_result::FAILED; + } + return Send_pkt_result::SUCCEEDED; + } + + public: + + Uplink_connection(Genode::Env &env, + Genode::Allocator &alloc, + Genode::Signal_context_capability sigh); + + void for_each_rx_packet(Handle_packet_func handle_packet); + + void notify_peer(); + + void send_ip(void const *ip_base, + Genode::size_t ip_size); +}; + +#endif /* _UPLINK_CONNECTION_H_ */ diff --git a/tool/autopilot.list b/tool/autopilot.list index 2a82b9f460..13728a833b 100644 --- a/tool/autopilot.list +++ b/tool/autopilot.list @@ -95,3 +95,4 @@ vm_stress_vbox5-debian32 vm_stress_vbox5-debian64 vmm_arm vmm_x86 +wg_fetchurl