nixos: add uplink option to children
Add an option to genode.core.children and genode.init.children for specifying a Nic driver for the exclusive use of the child for which it is added. This mechanism is to support the nic_router but it is reusable for arbitrary children.
This commit is contained in:
parent
de98f23758
commit
a91dda99d8
|
@ -4,7 +4,8 @@ with lib;
|
||||||
let
|
let
|
||||||
localPackages = pkgs.buildPackages;
|
localPackages = pkgs.buildPackages;
|
||||||
|
|
||||||
children' = config.lib.children.freeze config.genode.core.children;
|
children' = config.lib.children.freeze
|
||||||
|
(config.genode.core.children // config.genode.core.supportChildren);
|
||||||
|
|
||||||
coreErisCaps = with builtins;
|
coreErisCaps = with builtins;
|
||||||
let pkgNames = [ "rtc_drv" ];
|
let pkgNames = [ "rtc_drv" ];
|
||||||
|
@ -26,9 +27,12 @@ let
|
||||||
net = [ ];
|
net = [ ];
|
||||||
}.${config.genode.boot.storeBackend};
|
}.${config.genode.boot.storeBackend};
|
||||||
|
|
||||||
coreInputs = with builtins;
|
coreInputs =
|
||||||
|
# TODO: get rid of this?
|
||||||
|
with builtins;
|
||||||
concatMap (getAttr "extraInputs")
|
concatMap (getAttr "extraInputs")
|
||||||
(attrValues config.genode.core.children);
|
((attrValues config.genode.core.children)
|
||||||
|
++ (attrValues config.genode.core.supportChildren));
|
||||||
|
|
||||||
mergeManifests = inputs:
|
mergeManifests = inputs:
|
||||||
with builtins;
|
with builtins;
|
||||||
|
@ -150,6 +154,14 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
supportChildren = config.lib.types.children { extraOptions = { }; } // {
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Children added to support other children, such as drivers.
|
||||||
|
Do not manually add children here.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
boot = {
|
boot = {
|
||||||
|
|
|
@ -70,7 +70,7 @@ with lib;
|
||||||
, Init.ServiceRoute.parent "IO_PORT"
|
, Init.ServiceRoute.parent "IO_PORT"
|
||||||
]
|
]
|
||||||
, config = Init.Config::{
|
, config = Init.Config::{
|
||||||
, policies = [ ${toString policies} ]
|
, policies = [ ${toString policies} ] : List Init.Config.Policy.Type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
|
@ -23,193 +23,97 @@ with lib;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config =
|
||||||
|
# TODO: create drivers in both the first and second level inits
|
||||||
|
{
|
||||||
|
|
||||||
assertions = with builtins;
|
assertions = with builtins;
|
||||||
let
|
let
|
||||||
addrCheck = name: interface: {
|
addrCheck = name: interface: {
|
||||||
assertion = lessThan (length interface.ipv4.addresses) 2;
|
assertion = lessThan (length interface.ipv4.addresses) 2;
|
||||||
message = "Genode interfaces do not support multihoming.";
|
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 = clientList == [ ] || length clientList == 1;
|
|
||||||
message = "Multiple routes to Nic ${name}, ${clientList}";
|
|
||||||
};
|
};
|
||||||
in lib.lists.concatMap
|
routeCheck = name: interface: {
|
||||||
(f: lib.mapAttrsToList f config.networking.interfaces) [
|
assertion = lessThan (length interface.ipv4.routes) 2;
|
||||||
addrCheck
|
message = "Genode interfaces do not support multiple routes.";
|
||||||
routeCheck
|
};
|
||||||
policyCheck
|
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.core.children);
|
||||||
|
in {
|
||||||
|
assertion = 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:
|
hardware.genode.platform.policies = let
|
||||||
builtins.toFile (name + ".platform-policy.dhall") ''
|
mkPolicy = { name, platformPolicy }:
|
||||||
let Genode = env:DHALL_GENODE
|
pkgs.writeText "${name}.policy.dhall" ''${platformPolicy} "${name}"'';
|
||||||
|
|
||||||
in Genode.Init.Config.Policy::{
|
childPolicies = builtins.concatLists (lib.attrsets.mapAttrsToList
|
||||||
, service = "Platform"
|
(child: childAttrs:
|
||||||
, label = Genode.Init.LabelSelector.prefix "${name}.driver"
|
lib.attrsets.mapAttrsToList (uplink: uplinkAttrs:
|
||||||
, content =
|
mkPolicy {
|
||||||
[ Genode.Prelude.XML.leaf
|
name = "${child}-${uplink}.driver";
|
||||||
{ name = "pci"
|
inherit (uplinkAttrs) platformPolicy;
|
||||||
, attributes = toMap {
|
}) childAttrs.uplinks) config.genode.core.children);
|
||||||
, class = "ETHERNET"
|
|
||||||
, index = "${toString i}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
'') (builtins.attrNames config.networking.interfaces);
|
|
||||||
|
|
||||||
genode.core.children = mapAttrs' (name: interface:
|
in childPolicies;
|
||||||
let name' = name + ".driver";
|
|
||||||
in {
|
genode.core.supportChildren = let
|
||||||
name = name';
|
|
||||||
value = {
|
mkUplinkDriver = { policyPrefix, driver, verbose }: {
|
||||||
package = with pkgs.genodePackages;
|
package = with pkgs.genodePackages;
|
||||||
{
|
{
|
||||||
ipxe = ipxe_nic_drv;
|
ipxe = ipxe_nic_drv;
|
||||||
virtio = virtio_nic_drv;
|
virtio = virtio_nic_drv;
|
||||||
}.${interface.genode.driver};
|
}.${driver};
|
||||||
configFile = let
|
configFile = pkgs.writeText "driver.dhall" ''
|
||||||
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 Genode = env:DHALL_GENODE
|
||||||
|
|
||||||
let Init = Genode.Init
|
let Init = Genode.Init
|
||||||
|
|
||||||
in λ(binary : Text) -> Init.Child.flat
|
in λ(binary : Text) →
|
||||||
Init.Child.Attributes::{
|
Init.Child.flat
|
||||||
, 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 = lib.getEris "lib" (with pkgs.genodePackages;
|
|
||||||
{
|
|
||||||
lwip = vfs_lwip;
|
|
||||||
lxip = vfs_lxip;
|
|
||||||
}.${interface.genode.stack});
|
|
||||||
in {
|
|
||||||
name = name';
|
|
||||||
value = if interface.genode.stack == null then
|
|
||||||
null
|
|
||||||
else {
|
|
||||||
package = pkgs.genodePackages.vfs;
|
|
||||||
extraErisInputs = [ vfsPlugin ];
|
|
||||||
routeToNics = [ name ];
|
|
||||||
configFile = let
|
|
||||||
ram = {
|
|
||||||
lwip = 16;
|
|
||||||
lxip = 32;
|
|
||||||
}.${interface.genode.stack};
|
|
||||||
settings = with builtins;
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name = "label";
|
|
||||||
value = name;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "load";
|
|
||||||
value = vfsPlugin.cap;
|
|
||||||
}
|
|
||||||
] ++ 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::{
|
Init.Child.Attributes::{
|
||||||
, binary
|
, binary
|
||||||
, provides = [ "File_system" ]
|
, resources = Init.Resources::{ caps = 128, ram = Genode.units.MiB 4 }
|
||||||
, resources = Init.Resources::{
|
, routes = [ Init.ServiceRoute.parent "IO_MEM" ]
|
||||||
, caps = 128
|
|
||||||
, ram = Genode.units.MiB ${toString ram}
|
|
||||||
}
|
|
||||||
, config = Init.Config::{
|
, config = Init.Config::{
|
||||||
|
, attributes = toMap { verbose = "${
|
||||||
|
if verbose then "yes" else "no"
|
||||||
|
}" }
|
||||||
, policies =
|
, policies =
|
||||||
[ Init.Config.Policy::{
|
[ Init.Config.Policy::{
|
||||||
, service = "File_system"
|
, service = "Nic"
|
||||||
, label = Init.LabelSelector.suffix "${name'}"
|
, label = Init.LabelSelector.prefix "${policyPrefix}"
|
||||||
, 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;
|
otherDrivers = builtins.concatLists (lib.attrsets.mapAttrsToList
|
||||||
|
(child: childAttrs:
|
||||||
};
|
lib.attrsets.mapAttrsToList (uplink: uplinkAttrs: {
|
||||||
|
name = "${child}-${uplink}.driver";
|
||||||
|
value = mkUplinkDriver {
|
||||||
|
policyPrefix = "${child} -> ${uplink}";
|
||||||
|
inherit (uplinkAttrs) driver verbose;
|
||||||
|
};
|
||||||
|
}) childAttrs.uplinks) config.genode.core.children);
|
||||||
|
|
||||||
|
in builtins.listToAttrs otherDrivers;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,8 @@
|
||||||
example = literalExample "pkg.genodePackages.init";
|
example = literalExample "pkg.genodePackages.init";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uplinks = import ./uplinks-option.nix { inherit lib; };
|
||||||
|
|
||||||
} // extraOptions;
|
} // extraOptions;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
{ lib }:
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
mkOption {
|
||||||
|
default = { };
|
||||||
|
type = with types;
|
||||||
|
attrsOf (submodule {
|
||||||
|
options = {
|
||||||
|
driver = mkOption { type = types.enum [ "ipxe" "virtio" ]; };
|
||||||
|
platformPolicy = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = builtins.toFile "driver.policy.dhall" ''
|
||||||
|
let Genode = env:DHALL_GENODE
|
||||||
|
|
||||||
|
in λ(driverName : Text) →
|
||||||
|
Genode.Init.Config.Policy::{
|
||||||
|
, service = "Platform"
|
||||||
|
, label = Genode.Init.LabelSelector.prefix driverName
|
||||||
|
, content =
|
||||||
|
[ Genode.Prelude.XML.leaf
|
||||||
|
{ name = "pci", attributes = toMap { class = "ETHERNET" } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
verbose = lib.mkEnableOption "verbose driver logging";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue