Merge pull request #163958 from lukegb/networkd-main

nixos/networkd: configure /etc/systemd/networkd.conf
This commit is contained in:
Luke Granger-Brown 2022-04-11 02:01:19 +01:00 committed by GitHub
commit 4ea239aa70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 145 additions and 1 deletions

View file

@ -10,6 +10,36 @@ let
check = {
global = {
sectionNetwork = checkUnitConfig "Network" [
(assertOnlyFields [
"SpeedMeter"
"SpeedMeterIntervalSec"
"ManageForeignRoutingPolicyRules"
"ManageForeignRoutes"
"RouteTable"
])
(assertValueOneOf "SpeedMeter" boolValues)
(assertInt "SpeedMeterIntervalSec")
(assertValueOneOf "ManageForeignRoutingPolicyRules" boolValues)
(assertValueOneOf "ManageForeignRoutes" boolValues)
];
sectionDHCPv4 = checkUnitConfig "DHCPv4" [
(assertOnlyFields [
"DUIDType"
"DUIDRawData"
])
];
sectionDHCPv6 = checkUnitConfig "DHCPv6" [
(assertOnlyFields [
"DUIDType"
"DUIDRawData"
])
];
};
link = {
sectionLink = checkUnitConfig "Link" [
@ -871,6 +901,44 @@ let
};
};
networkdOptions = {
networkConfig = mkOption {
default = {};
example = { SpeedMeter = true; ManageForeignRoutingPolicyRules = false; };
type = types.addCheck (types.attrsOf unitOption) check.global.sectionNetwork;
description = ''
Each attribute in this set specifies an option in the
<literal>[Network]</literal> section of the networkd config.
See <citerefentry><refentrytitle>networkd.conf</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
dhcpV4Config = mkOption {
default = {};
example = { DUIDType = "vendor"; };
type = types.addCheck (types.attrsOf unitOption) check.global.sectionDHCPv4;
description = ''
Each attribute in this set specifies an option in the
<literal>[DHCPv4]</literal> section of the networkd config.
See <citerefentry><refentrytitle>networkd.conf</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
dhcpV6Config = mkOption {
default = {};
example = { DUIDType = "vendor"; };
type = types.addCheck (types.attrsOf unitOption) check.global.sectionDHCPv6;
description = ''
Each attribute in this set specifies an option in the
<literal>[DHCPv6]</literal> section of the networkd config.
See <citerefentry><refentrytitle>networkd.conf</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
};
linkOptions = commonNetworkOptions // {
# overwrite enable option from above
enable = mkOption {
@ -1519,6 +1587,39 @@ let
};
};
networkdConfig = { config, ... }: {
options = {
routeTables = mkOption {
default = {};
example = { foo = 27; };
type = with types; attrsOf int;
description = ''
Defines route table names as an attrset of name to number.
See <citerefentry><refentrytitle>networkd.conf</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
};
addRouteTablesToIPRoute2 = mkOption {
default = true;
example = false;
type = types.bool;
description = ''
If true and routeTables are set, then the specified route tables
will also be installed into /etc/iproute2/rt_tables.
'';
};
};
config = {
networkConfig = optionalAttrs (config.routeTables != { }) {
RouteTable = mapAttrsToList
(name: number: "${name}:${toString number}")
config.routeTables;
};
};
};
commonMatchText = def: optionalString (def.matchConfig != { }) ''
[Match]
${attrsToSection def.matchConfig}
@ -1600,6 +1701,20 @@ let
+ def.extraConfig;
};
renderConfig = def:
{ text = ''
[Network]
${attrsToSection def.networkConfig}
''
+ optionalString (def.dhcpV4Config != { }) ''
[DHCPv4]
${attrsToSection def.dhcpV4Config}
''
+ optionalString (def.dhcpV6Config != { }) ''
[DHCPv6]
${attrsToSection def.dhcpV6Config}
''; };
networkToUnit = name: def:
{ inherit (def) enable;
text = commonMatchText def
@ -1732,6 +1847,12 @@ in
description = "Definition of systemd networks.";
};
systemd.network.config = mkOption {
default = {};
type = with types; submodule [ { options = networkdOptions; } networkdConfig ];
description = "Definition of global systemd network config.";
};
systemd.network.units = mkOption {
description = "Definition of networkd units.";
default = {};
@ -1823,7 +1944,9 @@ in
systemd.services.systemd-networkd = {
wantedBy = [ "multi-user.target" ];
aliases = [ "dbus-org.freedesktop.network1.service" ];
restartTriggers = map (x: x.source) (attrValues unitFiles);
restartTriggers = map (x: x.source) (attrValues unitFiles) ++ [
config.environment.etc."systemd/networkd.conf".source
];
};
systemd.services.systemd-networkd-wait-online = {
@ -1846,6 +1969,17 @@ in
};
};
environment.etc."systemd/networkd.conf" = renderConfig cfg.config;
networking.iproute2 = mkIf (cfg.config.addRouteTablesToIPRoute2 && cfg.config.routeTables != { }) {
enable = mkDefault true;
rttablesExtraConfig = ''
# Extra tables defined in NixOS systemd.networkd.config.routeTables.
${concatStringsSep "\n" (mapAttrsToList (name: number: "${toString number} ${name}") cfg.config.routeTables)}
'';
};
services.resolved.enable = mkDefault true;
})
];

View file

@ -8,6 +8,9 @@ let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: {
environment.systemPackages = with pkgs; [ wireguard-tools ];
systemd.network = {
enable = true;
config = {
routeTables.custom = 23;
};
netdevs = {
"90-wg0" = {
netdevConfig = { Kind = "wireguard"; Name = "wg0"; };
@ -39,6 +42,7 @@ let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: {
address = [ "10.0.0.${nodeId}/32" ];
routes = [
{ routeConfig = { Gateway = "10.0.0.${nodeId}"; Destination = "10.0.0.0/24"; }; }
{ routeConfig = { Gateway = "10.0.0.${nodeId}"; Destination = "10.0.0.0/24"; Table = "custom"; }; }
];
};
"30-eth1" = {
@ -87,6 +91,12 @@ testScript = ''
node1.wait_for_unit("systemd-networkd-wait-online.service")
node2.wait_for_unit("systemd-networkd-wait-online.service")
# ================================
# Networkd Config
# ================================
node1.succeed("grep RouteTable=custom:23 /etc/systemd/networkd.conf")
node1.succeed("sudo ip route show table custom | grep '10.0.0.0/24 via 10.0.0.1 dev wg0 proto static'")
# ================================
# Wireguard
# ================================