Emery Hemingway
2afd2d08cc
Require that all init children declared by Nix be declared with an absolute path to the program binary.
216 lines
7.1 KiB
Nix
216 lines
7.1 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 = {
|
|
binary = with pkgs.genodePackages;
|
|
{
|
|
ipxe = "${ipxe_nic_drv}/bin/ipxe_nic_drv";
|
|
virtio = "${virtio_nic_drv}/bin/virtio_nic_drv";
|
|
}.${interface.genode.driver};
|
|
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 λ(binary : Text) -> Init.Child.flat
|
|
Init.Child.Attributes::{
|
|
, binary
|
|
, 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}/lib/vfs_lwip.lib.so";
|
|
lxip = "${vfs_lxip}/lib/vfs_lxip.lib.so";
|
|
}.${interface.genode.stack};
|
|
in {
|
|
name = name';
|
|
value = if interface.genode.stack == null then
|
|
null
|
|
else {
|
|
binary = "${pkgs.genodePackages.vfs}/bin/vfs";
|
|
routeToNics = [ name ];
|
|
configFile = let
|
|
ram = {
|
|
lwip = 16;
|
|
lxip = 32;
|
|
}.${interface.genode.stack};
|
|
settings = with builtins;
|
|
[
|
|
{
|
|
name = "label";
|
|
value = name;
|
|
}
|
|
{
|
|
name = "load";
|
|
value = vfsPlugin;
|
|
}
|
|
] ++ 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 λ(binary : Text) -> Init.Child.flat
|
|
Init.Child.Attributes::{
|
|
, binary
|
|
, 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;
|
|
|
|
};
|
|
|
|
}
|