summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/configuration.xml2
-rw-r--r--nixos/modules/services/networking/dhcpcd.nix1
-rw-r--r--nixos/modules/services/networking/networkmanager.nix5
-rw-r--r--nixos/modules/services/x11/redshift.nix2
-rw-r--r--nixos/modules/tasks/network-interfaces.nix184
5 files changed, 192 insertions, 2 deletions
diff --git a/nixos/doc/manual/configuration.xml b/nixos/doc/manual/configuration.xml
index 9bca53ae9040..e6d7dee251af 100644
--- a/nixos/doc/manual/configuration.xml
+++ b/nixos/doc/manual/configuration.xml
@@ -1235,7 +1235,7 @@ with other kernel modules.</para>
 <para>On 64-bit systems, if you want full acceleration for 32-bit
 programs such as Wine, you should also set the following:
 <programlisting>
-service.xserver.driSupport32Bit = true;
+services.xserver.driSupport32Bit = true;
 </programlisting>
 </para>
 
diff --git a/nixos/modules/services/networking/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix
index ea263b3c89de..08a5d6de6a2b 100644
--- a/nixos/modules/services/networking/dhcpcd.nix
+++ b/nixos/modules/services/networking/dhcpcd.nix
@@ -11,6 +11,7 @@ let
   ignoredInterfaces =
     map (i: i.name) (filter (i: i.ipAddress != null) (attrValues config.networking.interfaces))
     ++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges))
+    ++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bonds))
     ++ config.networking.dhcpcd.denyInterfaces;
 
   # Config file adapted from the one that ships with dhcpcd.
diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix
index 62bf38e4e708..40c20aae4ef0 100644
--- a/nixos/modules/services/networking/networkmanager.nix
+++ b/nixos/modules/services/networking/networkmanager.nix
@@ -146,6 +146,9 @@ in {
       { source = "${networkmanager_openconnect}/etc/NetworkManager/VPN/nm-openconnect-service.name";
         target = "NetworkManager/VPN/nm-openconnect-service.name";
       }
+      { source = "${networkmanager_pptp}/etc/NetworkManager/VPN/nm-pptp-service.name";
+        target = "NetworkManager/VPN/nm-pptp-service.name";
+      }
     ] ++ pkgs.lib.optional (cfg.appendNameservers == [] || cfg.insertNameservers == [])
            { source = overrideNameserversScript;
              target = "NetworkManager/dispatcher.d/02overridedns";
@@ -155,6 +158,7 @@ in {
         networkmanager_openvpn
         networkmanager_vpnc
         networkmanager_openconnect
+        networkmanager_pptp
         ];
 
     users.extraGroups = singleton {
@@ -199,6 +203,7 @@ in {
         networkmanager_openvpn
         networkmanager_vpnc
         networkmanager_openconnect
+        networkmanager_pptp
         ];
 
     services.udev.packages = cfg.packages;
diff --git a/nixos/modules/services/x11/redshift.nix b/nixos/modules/services/x11/redshift.nix
index bf7f974edc7b..b9ad962d8e46 100644
--- a/nixos/modules/services/x11/redshift.nix
+++ b/nixos/modules/services/x11/redshift.nix
@@ -40,12 +40,14 @@ in {
     systemd.services.redshift = {
       description = "Redshift colour temperature adjuster";
       requires = [ "display-manager.service" ];
+      after = [ "display-manager.service" ];
       script = ''
         ${pkgs.redshift}/bin/redshift \
           -l ${cfg.latitude}:${cfg.longitude} \
           -t ${toString cfg.temperature.day}:${toString cfg.temperature.night}
       '';
       environment = { DISPLAY = ":0"; };
+      serviceConfig.Restart = "always";
     };
   };
 }
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index b1ab989f130f..9619f0f5ebe7 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -7,6 +7,7 @@ let
   cfg = config.networking;
   interfaces = attrValues cfg.interfaces;
   hasVirtuals = any (i: i.virtual) interfaces;
+  hasBonds = cfg.bonds != { };
 
   interfaceOpts = { name, ... }: {
 
@@ -58,6 +59,15 @@ let
         '';
       };
 
+      mtu = mkOption {
+        default = null;
+        example = 9000;
+        type = types.nullOr types.int;
+        description = ''
+          MTU size for packets leaving the interface. Leave empty to use the default.
+        '';
+      };
+
       virtual = mkOption {
         default = false;
         type = types.bool;
@@ -219,6 +229,99 @@ in
 
     };
 
+    networking.bonds = mkOption {
+      default = { };
+      example = {
+        bond0 = {
+          interfaces = [ "eth0" "wlan0" ];
+          miimon = 100;
+          mode = "active-backup";
+        };
+        fatpipe.interfaces = [ "enp4s0f0" "enp4s0f1" "enp5s0f0" "enp5s0f1" ];
+      };
+      description = ''
+        This option allows you to define bond devices that aggregate multiple,
+        underlying networking interfaces together. The value of this option is
+        an attribute set. Each attribute specifies a bond, with the attribute
+        name specifying the name of the bond's network interface
+      '';
+
+      type = types.attrsOf types.optionSet;
+
+      options = {
+
+        interfaces = mkOption {
+          example = [ "enp4s0f0" "enp4s0f1" "wlan0" ];
+          type = types.listOf types.string;
+          description = "The interfaces to bond together";
+        };
+
+        miimon = mkOption {
+          default = null;
+          example = 100;
+          type = types.nullOr types.int;
+          description = ''
+            Miimon is the number of millisecond in between each round of polling
+            by the device driver for failed links. By default polling is not
+            enabled and the driver is trusted to properly detect and handle
+            failure scenarios.
+          '';
+        };
+
+        mode = mkOption {
+          default = null;
+          example = "active-backup";
+          type = types.nullOr types.string;
+          description = ''
+            The mode which the bond will be running. The default mode for
+            the bonding driver is balance-rr, optimizing for throughput.
+            More information about valid modes can be found at
+            https://www.kernel.org/doc/Documentation/networking/bonding.txt
+          '';
+        };
+
+      };
+    };
+
+    networking.vlans = mkOption {
+      default = { };
+      example = {
+        vlan0 = {
+          id = 3;
+          interface = "enp3s0";
+        };
+        vlan1 = {
+          id = 1;
+          interface = "wlan0";
+        };
+      };
+      description =
+        ''
+          This option allows you to define vlan devices that tag packets
+          on top of a physical interface. The value of this option is an
+          attribute set. Each attribute specifies a vlan, with the name
+          specifying the name of the vlan interface.
+        '';
+
+      type = types.attrsOf types.optionSet;
+
+      options = {
+
+        id = mkOption {
+          example = 1;
+          type = types.int;
+          description = "The vlan identifier";
+        };
+
+        interface = mkOption {
+          example = "enp4s0";
+          type = types.string;
+          description = "The interface the vlan will transmit packets through.";
+        };
+
+      };
+    };
+
     networking.useDHCP = mkOption {
       type = types.bool;
       default = true;
@@ -236,7 +339,15 @@ in
 
   config = {
 
-    boot.kernelModules = optional cfg.enableIPv6 "ipv6" ++ optional hasVirtuals "tun";
+    boot.kernelModules = [ ]
+      ++ optional cfg.enableIPv6 "ipv6"
+      ++ optional hasVirtuals "tun"
+      ++ optional hasBonds "bonding";
+
+    boot.extraModprobeConfig =
+      # This setting is intentional as it prevents default bond devices
+      # from being created.
+      optionalString hasBonds "options bonding max_bonds=0";
 
     environment.systemPackages =
       [ pkgs.host
@@ -342,6 +453,11 @@ in
                   echo "setting MAC address to ${i.macAddress}..."
                   ip link set "${i.name}" address "${i.macAddress}"
                 ''
+              + optionalString (i.mtu != null)
+                ''
+                  echo "setting MTU to ${toString i.mtu}..."
+                  ip link set "${i.name}" mtu "${toString i.mtu}"
+                ''
               + optionalString (i.ipAddress != null)
                 ''
                   cur=$(ip -4 -o a show dev "${i.name}" | awk '{print $4}')
@@ -397,6 +513,9 @@ in
             path = [ pkgs.bridge_utils pkgs.iproute ];
             script =
               ''
+                # Remove Dead Interfaces
+                ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
+
                 brctl addbr "${n}"
 
                 # Set bridge's hello time to 0 to avoid startup delays.
@@ -421,10 +540,73 @@ in
               '';
           };
 
+        createBondDevice = n: v:
+          let
+            deps = map (i: "sys-subsystem-net-devices-${i}.device") v.interfaces;
+          in
+          { description = "Bond Interface ${n}";
+            wantedBy = [ "network.target" "sys-subsystem-net-devices-${n}.device" ];
+            bindsTo = deps;
+            after = deps;
+            serviceConfig.Type = "oneshot";
+            serviceConfig.RemainAfterExit = true;
+            path = [ pkgs.ifenslave pkgs.iproute ];
+            script = ''
+              # Remove Dead Interfaces
+              ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
+
+              ip link add "${n}" type bond
+
+              # !!! There must be a better way to wait for the interface
+              while [ ! -d /sys/class/net/${n} ]; do sleep 0.1; done;
+
+              # Set the miimon and mode options
+              ${optionalString (v.miimon != null)
+                "echo ${toString v.miimon} > /sys/class/net/${n}/bonding/miimon"}
+              ${optionalString (v.mode != null)
+                "echo \"${v.mode}\" > /sys/class/net/${n}/bonding/mode"}
+
+              # Bring up the bridge and enslave the specified interfaces
+              ip link set "${n}" up
+              ${flip concatMapStrings v.interfaces (i: ''
+                ifenslave "${n}" "${i}"
+              '')}
+            '';
+            postStop = ''
+              ip link set "${n}" down
+              ifenslave -d "${n}"
+              ip link delete "${n}"
+            '';
+          };
+
+        createVlanDevice = n: v:
+          let
+            deps = [ "sys-subsystem-net-devices-${v.interface}.device" ];
+          in
+          { description = "Vlan Interface ${n}";
+            wantedBy = [ "network.target" "sys-subsystem-net-devices-${n}.device" ];
+            bindsTo = deps;
+            after = deps;
+            serviceConfig.Type = "oneshot";
+            serviceConfig.RemainAfterExit = true;
+            path = [ pkgs.iproute ];
+            script = ''
+              # Remove Dead Interfaces
+              ip link show "${n}" >/dev/null 2>&1 && ip link delete "${n}"
+              ip link add link "${v.interface}" "${n}" type vlan id "${toString v.id}"
+              ip link set "${n}" up
+            '';
+            postStop = ''
+              ip link delete "${n}"
+            '';
+          };
+
       in listToAttrs (
            map configureInterface interfaces ++
            map createTunDevice (filter (i: i.virtual) interfaces))
          // mapAttrs createBridgeDevice cfg.bridges
+         // mapAttrs createBondDevice cfg.bonds
+         // mapAttrs createVlanDevice cfg.vlans
          // { "network-setup" = networkSetup; };
 
     # Set the host and domain names in the activation script.  Don't