Retrieve ROMs in the common case by full store path. This reduces the need for route policies for driving relative requests into absolute package paths. Making library requests by absolute path required libraries to be stored in the core image as such, and it follows that program binaries should be handled in the same way. This makes requests to core and to a file-system store more consistent, and makes dependency detection more robust.
219 lines
7.2 KiB
Nix
219 lines
7.2 KiB
Nix
{ config, pkgs, lib, ... }:
|
|
|
|
with lib;
|
|
|
|
{
|
|
options = {
|
|
|
|
networking.interfaces = lib.mkOption {
|
|
type = with types;
|
|
attrsOf (submodule ({ ... }: {
|
|
options.genode = {
|
|
|
|
driver = mkOption { type = types.enum [ "ipxe" "virtio" ]; };
|
|
|
|
stack = mkOption {
|
|
type = with types; nullOr (enum [ "lwip" "lxip" ]);
|
|
default = "lwip";
|
|
};
|
|
|
|
};
|
|
}));
|
|
};
|
|
|
|
};
|
|
|
|
config = {
|
|
|
|
assertions = with builtins;
|
|
let
|
|
addrCheck = name: interface: {
|
|
assertion = lessThan (length interface.ipv4.addresses) 2;
|
|
message = "Genode interfaces do not support multihoming.";
|
|
};
|
|
routeCheck = name: interface: {
|
|
assertion = lessThan (length interface.ipv4.routes) 2;
|
|
message = "Genode interfaces do not support multiple routes.";
|
|
};
|
|
policyCheck = name: interface:
|
|
let
|
|
clientList = filter (x: x != null) (lib.mapAttrsToList
|
|
(childName: value:
|
|
if any (nic: nic == name) value.routeToNics then
|
|
childName
|
|
else
|
|
null) config.genode.init.children);
|
|
in {
|
|
assertion =
|
|
trace clientList (clientList == [ ] || length clientList == 1);
|
|
message = "Multiple routes to Nic ${name}, ${clientList}";
|
|
};
|
|
in lib.lists.concatMap
|
|
(f: lib.mapAttrsToList f config.networking.interfaces) [
|
|
addrCheck
|
|
routeCheck
|
|
policyCheck
|
|
];
|
|
|
|
hardware.genode.platform.policies = lib.lists.imap0 (i: name:
|
|
builtins.toFile (name + ".platform-policy.dhall") ''
|
|
let Genode = env:DHALL_GENODE
|
|
|
|
in Genode.Init.Config.Policy::{
|
|
, service = "Platform"
|
|
, label = Genode.Init.LabelSelector.prefix "${name}.driver"
|
|
, content =
|
|
[ Genode.Prelude.XML.leaf
|
|
{ name = "pci"
|
|
, attributes = toMap {
|
|
, class = "ETHERNET"
|
|
, index = "${toString i}"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
'') (builtins.attrNames config.networking.interfaces);
|
|
|
|
genode.core.children = mapAttrs' (name: interface:
|
|
let name' = name + ".driver";
|
|
in {
|
|
name = name';
|
|
value = let
|
|
binary = with pkgs.genodePackages;
|
|
{
|
|
ipxe = ipxe_nic_drv;
|
|
virtio = virtio_nic_drv;
|
|
}.${interface.genode.driver};
|
|
in {
|
|
inputs = [ binary ];
|
|
configFile = let
|
|
policy = lib.mapAttrsToList (childName: value:
|
|
if any (nic: nic == name) value.routeToNics then ''
|
|
Init.Config.Policy::{
|
|
, service = "Nic"
|
|
, label = Init.LabelSelector.prefix "nixos -> ${childName}"
|
|
}
|
|
'' else
|
|
"") config.genode.init.children;
|
|
|
|
in pkgs.writeText "${name'}.dhall" ''
|
|
let Genode = env:DHALL_GENODE
|
|
|
|
let Init = Genode.Init
|
|
|
|
in Init.Child.flat
|
|
Init.Child.Attributes::{
|
|
, binary = "${binary}/bin/${binary.pname}"
|
|
, provides = [ "Nic" ]
|
|
, resources = Init.Resources::{ caps = 128, ram = Genode.units.MiB 4 }
|
|
, routes = [ Init.ServiceRoute.parent "IO_MEM" ]
|
|
, config = Init.Config::{
|
|
, attributes = toMap { verbose = "true" }
|
|
, policies = [ ${
|
|
toString policy
|
|
} ] : List Init.Config.Policy.Type
|
|
}
|
|
}
|
|
'';
|
|
};
|
|
}) config.networking.interfaces;
|
|
|
|
genode.init.children = let
|
|
sockets = mapAttrs' (name: interface:
|
|
let
|
|
name' = name + ".sockets";
|
|
vfsPlugin = with pkgs.genodePackages;
|
|
{
|
|
lwip = vfs_lwip;
|
|
lxip = vfs_lxip;
|
|
}.${interface.genode.stack};
|
|
in {
|
|
name = name';
|
|
value = if interface.genode.stack == null then
|
|
null
|
|
else {
|
|
inputs = [ vfsPlugin ];
|
|
routeToNics = [ name ];
|
|
configFile = let
|
|
ram = {
|
|
lwip = 16;
|
|
lxip = 32;
|
|
}.${interface.genode.stack};
|
|
settings = with builtins;
|
|
[
|
|
{
|
|
name = "label";
|
|
value = name;
|
|
}
|
|
{
|
|
name = "load";
|
|
value = "${vfsPlugin}/lib/${vfsPlugin.pname}.lib.so";
|
|
}
|
|
] ++ lib.optionals (interface.ipv4.addresses != [ ])
|
|
(let addr = head interface.ipv4.addresses;
|
|
in [
|
|
{
|
|
name = "ip_addr";
|
|
value = addr.address;
|
|
}
|
|
{
|
|
name = "netmask";
|
|
value = if addr.prefixLength == 24 then
|
|
"255.255.255.0"
|
|
else
|
|
throw "missing prefix to netmask conversion";
|
|
}
|
|
]) ++ lib.optional (interface.ipv4.routes != [ ])
|
|
(let route = head interface.ipv4.routes;
|
|
in {
|
|
name = "gateway";
|
|
value = route.address;
|
|
}) ++ lib.optional (interface.useDHCP != null) {
|
|
name = "dhcp";
|
|
value = if interface.useDHCP then "true" else "false";
|
|
};
|
|
settingsMap = builtins.concatStringsSep ", " (map
|
|
({ name, value }:
|
|
''{ mapKey = "${name}", mapValue = "${value}" }'') settings);
|
|
in pkgs.writeText "${name'}.dhall" ''
|
|
let Genode = env:DHALL_GENODE
|
|
|
|
let Init = Genode.Init
|
|
|
|
in Init.Child.flat
|
|
Init.Child.Attributes::{
|
|
, binary = "${pkgs.genodePackages.vfs}/bin/vfs"
|
|
, provides = [ "File_system" ]
|
|
, resources = Init.Resources::{
|
|
, caps = 128
|
|
, ram = Genode.units.MiB ${toString ram}
|
|
}
|
|
, config = Init.Config::{
|
|
, policies =
|
|
[ Init.Config.Policy::{
|
|
, service = "File_system"
|
|
, label = Init.LabelSelector.suffix "${name'}"
|
|
, attributes = toMap { root = "/", writeable="yes" }
|
|
}
|
|
]
|
|
, content =
|
|
let VFS = Genode.VFS
|
|
|
|
in [ VFS.vfs
|
|
[ VFS.leafAttrs
|
|
"plugin"
|
|
([ ${settingsMap} ] : Genode.Prelude.Map.Type Text Text)
|
|
]
|
|
]
|
|
}
|
|
}
|
|
'';
|
|
};
|
|
}) config.networking.interfaces;
|
|
|
|
in lib.filterAttrs (n: v: v != null) sockets;
|
|
|
|
};
|
|
|
|
}
|