summary refs log tree commit diff
path: root/nixos/modules/tasks/network-interfaces.nix
diff options
context:
space:
mode:
authorVladimír Čunát <vcunat@gmail.com>2014-01-04 12:45:06 +0100
committerVladimír Čunát <vcunat@gmail.com>2014-01-04 18:34:53 +0100
commit9443129b08b37a6f4267d257cd8d42dd92a2539c (patch)
treeaec261361299cc2d85827dbcf5d03b594ae85e28 /nixos/modules/tasks/network-interfaces.nix
parentf78534ca0f8ec63d79370eb2367605579efba088 (diff)
parentf6d51f7717cffd8b220ce02498db8b8359b5964c (diff)
downloadnixlib-9443129b08b37a6f4267d257cd8d42dd92a2539c.tar
nixlib-9443129b08b37a6f4267d257cd8d42dd92a2539c.tar.gz
nixlib-9443129b08b37a6f4267d257cd8d42dd92a2539c.tar.bz2
nixlib-9443129b08b37a6f4267d257cd8d42dd92a2539c.tar.lz
nixlib-9443129b08b37a6f4267d257cd8d42dd92a2539c.tar.xz
nixlib-9443129b08b37a6f4267d257cd8d42dd92a2539c.tar.zst
nixlib-9443129b08b37a6f4267d257cd8d42dd92a2539c.zip
Merge master into stdenv-updates
Conflicts:
	pkgs/development/libraries/glibc/2.18/common.nix (take stdenv-updates)
	pkgs/misc/emulators/zsnes/default.nix (more complex, build tested)
	pkgs/top-level/all-packages.nix (auto-solved)
Diffstat (limited to 'nixos/modules/tasks/network-interfaces.nix')
-rw-r--r--nixos/modules/tasks/network-interfaces.nix184
1 files changed, 183 insertions, 1 deletions
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