Merge pull request #251290 from Majiir/systemd-initrd-networking-features
nixos/network-interfaces-systemd: support `vlans`, `bridges` in systemd-initrd
This commit is contained in:
@@ -173,6 +173,33 @@ let
|
||||
}];
|
||||
}));
|
||||
|
||||
bridgeNetworks = mkMerge (flip mapAttrsToList cfg.bridges (name: bridge: {
|
||||
netdevs."40-${name}" = {
|
||||
netdevConfig = {
|
||||
Name = name;
|
||||
Kind = "bridge";
|
||||
};
|
||||
};
|
||||
networks = listToAttrs (forEach bridge.interfaces (bi:
|
||||
nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) {
|
||||
DHCP = mkOverride 0 (dhcpStr false);
|
||||
networkConfig.Bridge = name;
|
||||
} ])));
|
||||
}));
|
||||
|
||||
vlanNetworks = mkMerge (flip mapAttrsToList cfg.vlans (name: vlan: {
|
||||
netdevs."40-${name}" = {
|
||||
netdevConfig = {
|
||||
Name = name;
|
||||
Kind = "vlan";
|
||||
};
|
||||
vlanConfig.Id = vlan.id;
|
||||
};
|
||||
networks."40-${vlan.interface}" = (mkMerge [ (genericNetwork (mkOverride 999)) {
|
||||
vlan = [ name ];
|
||||
} ]);
|
||||
}));
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@@ -182,7 +209,15 @@ in
|
||||
# Note this is if initrd.network.enable, not if
|
||||
# initrd.systemd.network.enable. By setting the latter and not the
|
||||
# former, the user retains full control over the configuration.
|
||||
boot.initrd.systemd.network = mkMerge [(genericDhcpNetworks true) interfaceNetworks];
|
||||
boot.initrd.systemd.network = mkMerge [
|
||||
(genericDhcpNetworks true)
|
||||
interfaceNetworks
|
||||
bridgeNetworks
|
||||
vlanNetworks
|
||||
];
|
||||
boot.initrd.availableKernelModules =
|
||||
optional (cfg.bridges != {}) "bridge" ++
|
||||
optional (cfg.vlans != {}) "8021q";
|
||||
})
|
||||
|
||||
(mkIf cfg.useNetworkd {
|
||||
@@ -212,19 +247,7 @@ in
|
||||
}
|
||||
(genericDhcpNetworks false)
|
||||
interfaceNetworks
|
||||
(mkMerge (flip mapAttrsToList cfg.bridges (name: bridge: {
|
||||
netdevs."40-${name}" = {
|
||||
netdevConfig = {
|
||||
Name = name;
|
||||
Kind = "bridge";
|
||||
};
|
||||
};
|
||||
networks = listToAttrs (forEach bridge.interfaces (bi:
|
||||
nameValuePair "40-${bi}" (mkMerge [ (genericNetwork (mkOverride 999)) {
|
||||
DHCP = mkOverride 0 (dhcpStr false);
|
||||
networkConfig.Bridge = name;
|
||||
} ])));
|
||||
})))
|
||||
bridgeNetworks
|
||||
(mkMerge (flip mapAttrsToList cfg.bonds (name: bond: {
|
||||
netdevs."40-${name}" = {
|
||||
netdevConfig = {
|
||||
@@ -377,18 +400,7 @@ in
|
||||
} ]);
|
||||
};
|
||||
})))
|
||||
(mkMerge (flip mapAttrsToList cfg.vlans (name: vlan: {
|
||||
netdevs."40-${name}" = {
|
||||
netdevConfig = {
|
||||
Name = name;
|
||||
Kind = "vlan";
|
||||
};
|
||||
vlanConfig.Id = vlan.id;
|
||||
};
|
||||
networks."40-${vlan.interface}" = (mkMerge [ (genericNetwork (mkOverride 999)) {
|
||||
vlan = [ name ];
|
||||
} ]);
|
||||
})))
|
||||
vlanNetworks
|
||||
];
|
||||
|
||||
# We need to prefill the slaved devices with networking options
|
||||
|
||||
@@ -764,6 +764,7 @@ in {
|
||||
systemd-cryptenroll = handleTest ./systemd-cryptenroll.nix {};
|
||||
systemd-credentials-tpm2 = handleTest ./systemd-credentials-tpm2.nix {};
|
||||
systemd-escaping = handleTest ./systemd-escaping.nix {};
|
||||
systemd-initrd-bridge = handleTest ./systemd-initrd-bridge.nix {};
|
||||
systemd-initrd-btrfs-raid = handleTest ./systemd-initrd-btrfs-raid.nix {};
|
||||
systemd-initrd-luks-fido2 = handleTest ./systemd-initrd-luks-fido2.nix {};
|
||||
systemd-initrd-luks-keyfile = handleTest ./systemd-initrd-luks-keyfile.nix {};
|
||||
@@ -778,6 +779,7 @@ in {
|
||||
systemd-initrd-networkd = handleTest ./systemd-initrd-networkd.nix {};
|
||||
systemd-initrd-networkd-ssh = handleTest ./systemd-initrd-networkd-ssh.nix {};
|
||||
systemd-initrd-networkd-openvpn = handleTest ./initrd-network-openvpn { systemdStage1 = true; };
|
||||
systemd-initrd-vlan = handleTest ./systemd-initrd-vlan.nix {};
|
||||
systemd-journal = handleTest ./systemd-journal.nix {};
|
||||
systemd-machinectl = handleTest ./systemd-machinectl.nix {};
|
||||
systemd-networkd = handleTest ./systemd-networkd.nix {};
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import ./make-test-python.nix ({ lib, ... }: {
|
||||
name = "systemd-initrd-bridge";
|
||||
meta.maintainers = [ lib.maintainers.majiir ];
|
||||
|
||||
# Tests bridge interface configuration in systemd-initrd.
|
||||
#
|
||||
# The 'a' and 'b' nodes are connected to a 'bridge' node through different
|
||||
# links. The 'bridge' node configures a bridge across them. It waits forever
|
||||
# in initrd (stage 1) with networking enabled. 'a' and 'b' ping 'bridge' to
|
||||
# test connectivity with the bridge interface. Then, 'a' pings 'b' to test
|
||||
# the bridge itself.
|
||||
|
||||
nodes = {
|
||||
bridge = { config, lib, ... }: {
|
||||
boot.initrd.systemd.enable = true;
|
||||
boot.initrd.network.enable = true;
|
||||
boot.initrd.systemd.services.boot-blocker = {
|
||||
before = [ "initrd.target" ];
|
||||
wantedBy = [ "initrd.target" ];
|
||||
script = "sleep infinity";
|
||||
serviceConfig.Type = "oneshot";
|
||||
};
|
||||
|
||||
networking.primaryIPAddress = "192.168.1.${toString config.virtualisation.test.nodeNumber}";
|
||||
|
||||
virtualisation.vlans = [ 1 2 ];
|
||||
networking.bridges.br0.interfaces = [ "eth1" "eth2" ];
|
||||
|
||||
networking.interfaces = {
|
||||
eth1.ipv4.addresses = lib.mkForce [];
|
||||
eth2.ipv4.addresses = lib.mkForce [];
|
||||
br0.ipv4.addresses = [{
|
||||
address = config.networking.primaryIPAddress;
|
||||
prefixLength = 24;
|
||||
}];
|
||||
};
|
||||
};
|
||||
|
||||
a = {
|
||||
virtualisation.vlans = [ 1 ];
|
||||
};
|
||||
|
||||
b = { config, ... }: {
|
||||
virtualisation.vlans = [ 2 ];
|
||||
networking.primaryIPAddress = lib.mkForce "192.168.1.${toString config.virtualisation.test.nodeNumber}";
|
||||
networking.interfaces.eth1.ipv4.addresses = lib.mkForce [{
|
||||
address = config.networking.primaryIPAddress;
|
||||
prefixLength = 24;
|
||||
}];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
a.wait_for_unit("network.target")
|
||||
b.wait_for_unit("network.target")
|
||||
|
||||
a.succeed("ping -n -w 10 -c 1 bridge >&2")
|
||||
b.succeed("ping -n -w 10 -c 1 bridge >&2")
|
||||
|
||||
a.succeed("ping -n -w 10 -c 1 b >&2")
|
||||
'';
|
||||
})
|
||||
@@ -0,0 +1,59 @@
|
||||
import ./make-test-python.nix ({ lib, ... }: {
|
||||
name = "systemd-initrd-vlan";
|
||||
meta.maintainers = [ lib.maintainers.majiir ];
|
||||
|
||||
# Tests VLAN interface configuration in systemd-initrd.
|
||||
#
|
||||
# Two nodes are configured for a tagged VLAN. (Note that they also still have
|
||||
# their ordinary eth0 and eth1 interfaces, which are not VLAN-tagged.)
|
||||
#
|
||||
# The 'server' node waits forever in initrd (stage 1) with networking
|
||||
# enabled. The 'client' node pings it to test network connectivity.
|
||||
|
||||
nodes = let
|
||||
network = id: {
|
||||
networking = {
|
||||
vlans."eth1.10" = {
|
||||
id = 10;
|
||||
interface = "eth1";
|
||||
};
|
||||
interfaces."eth1.10" = {
|
||||
ipv4.addresses = [{
|
||||
address = "192.168.10.${id}";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
};
|
||||
};
|
||||
};
|
||||
in {
|
||||
# Node that will use initrd networking.
|
||||
server = network "1" // {
|
||||
boot.initrd.systemd.enable = true;
|
||||
boot.initrd.network.enable = true;
|
||||
boot.initrd.systemd.services.boot-blocker = {
|
||||
before = [ "initrd.target" ];
|
||||
wantedBy = [ "initrd.target" ];
|
||||
script = "sleep infinity";
|
||||
serviceConfig.Type = "oneshot";
|
||||
};
|
||||
};
|
||||
|
||||
# Node that will ping the server.
|
||||
client = network "2";
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
client.wait_for_unit("network.target")
|
||||
|
||||
# Wait for the regular (untagged) interface to be up.
|
||||
def server_is_up(_) -> bool:
|
||||
status, _ = client.execute("ping -n -c 1 server >&2")
|
||||
return status == 0
|
||||
with client.nested("waiting for server to come up"):
|
||||
retry(server_is_up)
|
||||
|
||||
# Try to ping the (tagged) VLAN interface.
|
||||
client.succeed("ping -n -w 10 -c 1 192.168.10.1 >&2")
|
||||
'';
|
||||
})
|
||||
Reference in New Issue
Block a user