diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix
index 6a8f20bab5b..4bbb5a3a166 100644
--- a/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -46,6 +46,23 @@ in
systemd.services =
let
+ deviceDependency = dev:
+ if (config.boot.isContainer == false)
+ then
+ # Trust udev when not in the container
+ [ (subsystemDevice dev) ]
+ else
+ # When in the container, check whether the interface is built from other definitions
+ if (hasAttr dev cfg.bridges) ||
+ (hasAttr dev cfg.bonds) ||
+ (hasAttr dev cfg.macvlans) ||
+ (hasAttr dev cfg.sits) ||
+ (hasAttr dev cfg.vlans) ||
+ (hasAttr dev cfg.vswitches) ||
+ (hasAttr dev cfg.wlanInterfaces)
+ then [ "${dev}-netdev.service" ]
+ else [];
+
networkLocalCommands = {
after = [ "network-setup.service" ];
bindsTo = [ "network-setup.service" ];
@@ -120,8 +137,8 @@ in
# order before network-setup because the routes that are configured
# there may need ip addresses configured
before = [ "network-setup.service" ];
- bindsTo = [ (subsystemDevice i.name) ];
- after = [ (subsystemDevice i.name) "network-pre.target" ];
+ bindsTo = deviceDependency i.name;
+ after = [ "network-pre.target" ] ++ (deviceDependency i.name);
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
path = [ pkgs.iproute ];
@@ -179,7 +196,7 @@ in
createBridgeDevice = n: v: nameValuePair "${n}-netdev"
(let
- deps = map subsystemDevice v.interfaces;
+ deps = if config.boot.isContainer then [] else map subsystemDevice v.interfaces;
in
{ description = "Bridge Interface ${n}";
wantedBy = [ "network-setup.service" (subsystemDevice n) ];
@@ -220,7 +237,7 @@ in
createVswitchDevice = n: v: nameValuePair "${n}-netdev"
(let
- deps = map subsystemDevice v.interfaces;
+ deps = if config.boot.isContainer then [] else map subsystemDevice v.interfaces;
ofRules = pkgs.writeText "vswitch-${n}-openFlowRules" v.openFlowRules;
in
{ description = "Open vSwitch Interface ${n}";
@@ -253,7 +270,7 @@ in
createBondDevice = n: v: nameValuePair "${n}-netdev"
(let
- deps = map subsystemDevice v.interfaces;
+ deps = if config.boot.isContainer then [] else map subsystemDevice v.interfaces;
in
{ description = "Bond Interface ${n}";
wantedBy = [ "network-setup.service" (subsystemDevice n) ];
@@ -291,7 +308,7 @@ in
createMacvlanDevice = n: v: nameValuePair "${n}-netdev"
(let
- deps = [ (subsystemDevice v.interface) ];
+ deps = deviceDependency v.interface;
in
{ description = "Vlan Interface ${n}";
wantedBy = [ "network-setup.service" (subsystemDevice n) ];
@@ -316,7 +333,7 @@ in
createSitDevice = n: v: nameValuePair "${n}-netdev"
(let
- deps = optional (v.dev != null) (subsystemDevice v.dev);
+ deps = optional (v.dev != null) (deviceDependency v.dev);
in
{ description = "6-to-4 Tunnel Interface ${n}";
wantedBy = [ "network-setup.service" (subsystemDevice n) ];
@@ -344,7 +361,7 @@ in
createVlanDevice = n: v: nameValuePair "${n}-netdev"
(let
- deps = [ (subsystemDevice v.interface) ];
+ deps = deviceDependency v.interface;
in
{ description = "Vlan Interface ${n}";
wantedBy = [ "network-setup.service" (subsystemDevice n) ];
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index cac7e6b02eb..aae4dc5fdad 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -310,9 +310,9 @@ in
generate a random 32-bit ID using the following commands:
cksum /etc/machine-id | while read c rest; do printf "%x" $c; done
-
+
(this derives it from the machine-id that systemd generates) or
-
+
head -c4 /dev/urandom | od -A none -t x4
'';
};
@@ -972,12 +972,17 @@ in
'';
};
} // (listToAttrs (flip map interfaces (i:
+ let
+ deviceDependency = if config.boot.isContainer
+ then []
+ else [ (subsystemDevice i.name) ];
+ in
nameValuePair "network-link-${i.name}"
{ description = "Link configuration of ${i.name}";
wantedBy = [ "network-interfaces.target" ];
before = [ "network-interfaces.target" ];
- bindsTo = [ (subsystemDevice i.name) ];
- after = [ (subsystemDevice i.name) "network-pre.target" ];
+ bindsTo = deviceDependency;
+ after = [ "network-pre.target" ] ++ deviceDependency;
path = [ pkgs.iproute ];
serviceConfig = {
Type = "oneshot";
diff --git a/nixos/release.nix b/nixos/release.nix
index bff17da607f..10c624afebc 100644
--- a/nixos/release.nix
+++ b/nixos/release.nix
@@ -227,6 +227,7 @@ in rec {
tests.containers-bridge = callTest tests/containers-bridge.nix {};
tests.containers-imperative = callTest tests/containers-imperative.nix {};
tests.containers-extra_veth = callTest tests/containers-extra_veth.nix {};
+ tests.containers-physical_interfaces = callTest tests/containers-physical_interfaces.nix {};
tests.docker = hydraJob (import tests/docker.nix { system = "x86_64-linux"; });
tests.dnscrypt-proxy = callTest tests/dnscrypt-proxy.nix { system = "x86_64-linux"; };
tests.ecryptfs = callTest tests/ecryptfs.nix {};
diff --git a/nixos/tests/containers-physical_interfaces.nix b/nixos/tests/containers-physical_interfaces.nix
new file mode 100644
index 00000000000..4a53f8c824f
--- /dev/null
+++ b/nixos/tests/containers-physical_interfaces.nix
@@ -0,0 +1,66 @@
+
+import ./make-test.nix ({ pkgs, ...} : {
+ name = "containers-physical_interfaces";
+ meta = with pkgs.stdenv.lib.maintainers; {
+ maintainers = [ kampfschlaefer ];
+ };
+
+ nodes = {
+ server = { config, pkgs, ... }:
+ {
+ virtualisation.memorySize = 256;
+ virtualisation.vlans = [ 1 ];
+
+ containers.server = {
+ privateNetwork = true;
+ interfaces = [ "eth1" ];
+
+ config = {
+ networking.interfaces.eth1 = {
+ ip4 = [ { address = "10.10.0.1"; prefixLength = 24; } ];
+ };
+ networking.firewall.enable = false;
+ };
+ };
+ };
+ client = { config, pkgs, ... }: {
+ virtualisation.memorySize = 256;
+ virtualisation.vlans = [ 1 ];
+
+ containers.client = {
+ privateNetwork = true;
+ interfaces = [ "eth1" ];
+
+ config = {
+ networking.bridges.br0.interfaces = [ "eth1" ];
+ networking.interfaces.br0 = {
+ ip4 = [ { address = "10.10.0.2"; prefixLength = 24; } ];
+ };
+ networking.firewall.enable = false;
+ };
+ };
+ };
+ };
+
+ testScript = ''
+ startAll;
+
+ $server->waitForUnit("default.target");
+ $server->execute("ip link >&2");
+
+ $server->succeed("ip link show dev eth1 >&2");
+
+ $server->succeed("nixos-container start server");
+ $server->waitForUnit("container\@server");
+ $server->succeed("systemctl -M server list-dependencies network-addresses-eth1.service >&2");
+
+ $server->succeed("nixos-container run server -- ip a show dev eth1 >&2");
+
+ $client->waitForUnit("default.target");
+ $client->succeed("nixos-container start client");
+ $client->waitForUnit("container\@client");
+ $client->succeed("systemctl -M client list-dependencies network-addresses-br0.service >&2");
+ $client->succeed("systemctl -M client status -n 30 -l network-addresses-br0.service");
+ $client->succeed("nixos-container run client -- ping -w 10 -c 1 -n 10.10.0.1");
+ '';
+})