{ config, pkgs, lib, ... }: with lib; { options.networking.interfaces = lib.mkOption { type = with types; attrsOf (submodule ({ ... }: { options.genode = { driver = mkOption { type = types.enum [ "ipxe" "virtio" ]; default = "ipxe"; }; stack = mkOption { type = types.enum [ "lwip" "lxip" ]; default = "lwip"; }; }; })); }; config.genode.init.children = let inherit (builtins) toFile; nics = mapAttrs' (name: interface: let name' = "nic." + name; in { name = name'; value = { inputs = with pkgs.genodePackages; { ipxe = [ ipxe_nic_drv ]; virtio = [ virtio_nic_drv ]; }.${interface.genode.driver}; configFile = toFile "${name'}.dhall" '' let Genode = env:DHALL_GENODE let Init = Genode.Init in Init.Child.flat Init.Child.Attributes::{ , binary = "virtio_pci_nic" , provides = [ "Nic" ] , resources = Init.Resources::{ , caps = 128 , ram = Genode.units.MiB 4 } , routes = [ Init.ServiceRoute.parent "IO_MEM" ] , config = Init.Config::{ , policies = [ Init.Config.Policy::{ , service = "Nic" , label = Init.LabelSelector.prefix "sockets.${name}" } ] } } ''; }; }) config.networking.interfaces; sockets = mapAttrs' (name: interface: let name' = "sockets." + name; in { name = name'; value = { inputs = with pkgs.genodePackages; { lwip = [ vfs_lwip ]; lxip = [ vfs_lixp ]; }.${interface.genode.stack}; configFile = let ipv4 = builtins.head interface.ipv4.addresses; in toFile "${name'}.dhall" '' let Genode = env:DHALL_GENODE let Init = Genode.Init in Init.Child.flat Init.Child.Attributes::{ , binary = "vfs" , provides = [ "File_system" ] , resources = Init.Resources::{ caps = 128, ram = Genode.units.MiB 16 } , config = Init.Config::{ , policies = [ Init.Config.Policy::{ , service = "File_system" , label = Init.LabelSelector.suffix "sockets" , attributes = toMap { root = "/" } } ] , content = let XML = Genode.Prelude.XML in [ XML.element { name = "vfs" , attributes = XML.emptyAttributes , content = [ XML.leaf { name = "lwip" , attributes = toMap { ip_addr = "${ipv4.address}", netmask = "${ if ipv4.prefixLength == 24 then "255.255.255.0" else throw "missing prefix to netmask conversion" }" } } ] } ] } } ''; }; }) config.networking.interfaces; in nics // sockets // { platform_drv = { inputs = [ pkgs.genodePackages.platform_drv ]; configFile = let policies = concatMapStrings (name: '' Init.Config.Policy::{ , service = "Platform" , label = Init.LabelSelector.prefix "nic.${name}" , content = [ Genode.Prelude.XML.leaf { name = "pci", attributes = toMap { class = "ETHERNET" } } ] } '') (builtins.attrNames config.networking.interfaces); in toFile "platform_drv.dhall" '' let Genode = env:DHALL_GENODE let Init = Genode.Init let label = \(_ : Text) -> { local = _, route = _ } in Init.Child.flat Init.Child.Attributes::{ , binary = "platform_drv" , resources = Init.Resources::{ , caps = 800 , ram = Genode.units.MiB 4 , constrainPhys = True } , reportRoms = [ label "acpi" ] , provides = [ "Platform" ] , routes = [ Init.ServiceRoute.parent "IRQ" , Init.ServiceRoute.parent "IO_MEM" , Init.ServiceRoute.parent "IO_PORT" ] , config = Init.Config::{ , policies = [ ${policies} ] } } ''; }; acpi_drv = { inputs = [ pkgs.genodePackages.acpi_drv ]; configFile = toFile "acpi_drv.dhall" '' let Genode = env:DHALL_GENODE let Init = Genode.Init let label = \(_ : Text) -> { local = _, route = _ } in Init.Child.flat Init.Child.Attributes::{ , binary = "acpi_drv" , resources = Init.Resources::{ , caps = 400 , ram = Genode.units.MiB 4 , constrainPhys = True } , romReports = [ label "acpi" ] , routes = [ Init.ServiceRoute.parent "IRQ" , Init.ServiceRoute.parent "IO_MEM" , Init.ServiceRoute.parent "IO_PORT" ] } ''; }; }; }