From 76a3c30471e57faaa75f4ed957c12f13e9f92d90 Mon Sep 17 00:00:00 2001
From: Franz Pletz <fpletz@fnordicwalking.de>
Date: Thu, 9 Feb 2017 23:08:48 +0100
Subject: [PATCH 1/2] network-interfaces service: fix bindsTo deps for masters

Previously, netdev units for network interfaces defined in the nixos
configurations would bindTo the systemd device unit of the interface if
not in a container.

In situations where you switch to a new nixos configration with changes
to network-setup.service (like nameservers) and have stacked interfaces
like vlans on a bond, it would fail to propagate restarts to the netdevs
correctly resulting with broken networking. The bond would be present
but no vlan interfaces rendering the machine unreachable.

My fear is that the udev events fail to propagate correctly while a systemd
transaction that is also restarting the triggered netdev service is running.
This commit changes this behaviour so netdev services bindTo other netdev
services if present and otherwise fall back to the previous behaviour.

We also noticed that stacked interfaces would sometimes seemingly be stopped
in the wrong order. For instance in the above example, the bond interface
would be deleted before the vlan interfaces resulting in the vlan interfaces
not being present when their service is being stopped. This would cause the
systemd transaction to fail and thus break networking. Their postStop hooks
are now allowed to fail as we have reached the desired state.
---
 .../tasks/network-interfaces-scripted.nix     | 34 ++++++++-----------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix
index 062598de83e..cf90f05e8d3 100644
--- a/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -47,21 +47,17 @@ in
       let
 
         deviceDependency = dev:
-          if (config.boot.isContainer == false)
-          then
-            # Trust udev when not in the container
-            optional (dev != null) (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 [];
+          # Use systemd service if we manage device creation, else
+          # trust udev when not in a container
+          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 optional (dev != null && !config.boot.isContainer) (subsystemDevice dev);
 
         networkLocalCommands = {
           after = [ "network-setup.service" ];
@@ -198,7 +194,7 @@ in
               user "${i.virtualOwner}"
             '';
             postStop = ''
-              ip link del ${i.name}
+              ip link del ${i.name} || true
             '';
           };
 
@@ -335,7 +331,7 @@ in
               ip link set "${n}" up
             '';
             postStop = ''
-              ip link delete "${n}"
+              ip link delete "${n}" || true
             '';
           });
 
@@ -363,7 +359,7 @@ in
               ip link set "${n}" up
             '';
             postStop = ''
-              ip link delete "${n}"
+              ip link delete "${n}" || true
             '';
           });
 
@@ -387,7 +383,7 @@ in
               ip link set "${n}" up
             '';
             postStop = ''
-              ip link delete "${n}"
+              ip link delete "${n}" || true
             '';
           });
 

From 741770c99abbd6a165b5a7b0d8206aebba671de7 Mon Sep 17 00:00:00 2001
From: Franz Pletz <fpletz@fnordicwalking.de>
Date: Sat, 18 Feb 2017 04:54:15 +0100
Subject: [PATCH 2/2] network-interface service: tuntap ifs have netdev
 services

---
 nixos/modules/tasks/network-interfaces-scripted.nix | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix
index cf90f05e8d3..9264434d843 100644
--- a/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -49,7 +49,8 @@ in
         deviceDependency = dev:
           # Use systemd service if we manage device creation, else
           # trust udev when not in a container
-          if (hasAttr dev cfg.bridges) ||
+          if (hasAttr dev (filterAttrs (k: v: v.virtual) cfg.interfaces)) ||
+             (hasAttr dev cfg.bridges) ||
              (hasAttr dev cfg.bonds) ||
              (hasAttr dev cfg.macvlans) ||
              (hasAttr dev cfg.sits) ||