about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorrnhmjoj <rnhmjoj@inventati.org>2017-07-27 16:23:20 +0200
committerrnhmjoj <rnhmjoj@inventati.org>2018-02-17 13:57:58 +0100
commitd00c91c5dab1428941c4ee61e341b01a26f14c90 (patch)
tree47bfbddbcea58c712e49084eaeb57a7c7a6c8ab5 /nixos
parent05f5cdcf66ecc3e56df699c37bbdba7b1a8c107b (diff)
downloadnixlib-d00c91c5dab1428941c4ee61e341b01a26f14c90.tar
nixlib-d00c91c5dab1428941c4ee61e341b01a26f14c90.tar.gz
nixlib-d00c91c5dab1428941c4ee61e341b01a26f14c90.tar.bz2
nixlib-d00c91c5dab1428941c4ee61e341b01a26f14c90.tar.lz
nixlib-d00c91c5dab1428941c4ee61e341b01a26f14c90.tar.xz
nixlib-d00c91c5dab1428941c4ee61e341b01a26f14c90.tar.zst
nixlib-d00c91c5dab1428941c4ee61e341b01a26f14c90.zip
nixos/networking-interfaces: make static routes configurable
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/tasks/network-interfaces-scripted.nix66
-rw-r--r--nixos/modules/tasks/network-interfaces.nix63
2 files changed, 107 insertions, 22 deletions
diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix
index 63d07832d105..9dba6d1bd0a2 100644
--- a/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -185,33 +185,57 @@ let
             path = [ pkgs.iproute ];
             script =
               ''
-                # FIXME: shouldn't this be done in network-link?
-                echo "bringing up interface..."
-                ip link set "${i.name}" up
-
                 state="/run/nixos/network/addresses/${i.name}"
+                mkdir -p $(dirname "$state")
 
+                ${flip concatMapStrings ips (ip:
+                  let
+                    cidr = "${ip.address}/${toString ip.prefixLength}";
+                  in
+                  ''
+                    echo "${cidr}" >> $state
+                    echo -n "adding address ${cidr}... "
+                    if out=$(ip addr add "${cidr}" dev "${i.name}" 2>&1); then
+                      echo "done"
+                    elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then
+                      echo "failed"
+                      exit 1
+                    fi
+                  ''
+                )}
+
+                state="/run/nixos/network/routes/${i.name}"
                 mkdir -p $(dirname "$state")
 
-              '' + flip concatMapStrings (ips) (ip:
-                let
-                  address = "${ip.address}/${toString ip.prefixLength}";
-                in
-                ''
-                  echo "${address}" >> $state
-                  if out=$(ip addr add "${address}" dev "${i.name}" 2>&1); then
-                    echo "added ip ${address}"
-                  elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then
-                    echo "failed to add ${address}"
-                    exit 1
-                  fi
-                '');
+                ${flip concatMapStrings (i.ipv4Routes ++ i.ipv6Routes) (route:
+                  let
+                    cidr = "${route.address}/${toString route.prefixLength}";
+                    nextHop = optionalString (route.nextHop != null) ''via "${route.nextHop}"'';
+                  in
+                  ''
+                     echo "${cidr}" >> $state
+                     echo -n "adding route ${cidr}... "
+                     if out=$(ip route add "${cidr}" ${route.options} ${nextHop} dev "${i.name}" 2>&1); then
+                       echo "done"
+                     elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then
+                       echo "failed"
+                       exit 1
+                     fi
+                  ''
+                )}
+              '';
             preStop = ''
+              state="/run/nixos/network/routes/${i.name}"
+              while read cidr; do
+                echo -n "deleting route $cidr... "
+                ip route del "$cidr" dev "${i.name}" >/dev/null 2>&1 && echo "done" || echo "failed"
+              done < "$state"
+              rm -f "$state"
+
               state="/run/nixos/network/addresses/${i.name}"
-              while read address; do
-                echo -n "deleting $address..."
-                ip addr del "$address" dev "${i.name}" >/dev/null 2>&1 || echo -n " Failed"
-                echo ""
+              while read cidr; do
+                echo -n "deleting address $cidr... "
+                ip addr del "$cidr" dev "${i.name}" >/dev/null 2>&1 && echo "done" || echo "failed"
               done < "$state"
               rm -f "$state"
             '';
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index f80c5045c07d..d437a829be5f 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -101,7 +101,7 @@ let
         address = mkOption {
           type = types.str;
           description = ''
-            IPv${toString v} address of the interface.  Leave empty to configure the
+            IPv${toString v} address of the interface. Leave empty to configure the
             interface using DHCP.
           '';
         };
@@ -116,6 +116,40 @@ let
       };
     };
 
+  routeOpts = v:
+  { options = {
+      address = mkOption {
+        type = types.str;
+        description = "IPv${toString v} address of the network.";
+      };
+
+      prefixLength = mkOption {
+        type = types.addCheck types.int (n: n >= 0 && n <= (if v == 4 then 32 else 128));
+        description = ''
+          Subnet mask of the network, specified as the number of
+          bits in the prefix (<literal>${if v == 4 then "24" else "64"}</literal>).
+        '';
+      };
+
+      nextHop = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        description = "IPv${toString v} address of the next hop.";
+      };
+
+      options = mkOption {
+        type = types.str;
+        default = "";
+        example = "mtu 1492 window 524288";
+        description = ''
+          Other route options. See the symbol <literal>OPTION</literal>
+          in the <literal>ip-route(8)</literal> manual page for the details.
+        '';
+      };
+
+    };
+  };
+
   gatewayCoerce = address: { inherit address; };
 
   gatewayOpts = { ... }: {
@@ -199,6 +233,30 @@ let
         '';
       };
 
+      ipv4Routes = mkOption {
+        default = [];
+        example = [
+          { address = "10.0.0.0"; prefixLength = 16; }
+          { address = "192.168.2.0"; prefixLength = 24; nextHop = "192.168.1.1"; }
+        ];
+        type = with types; listOf (submodule (routeOpts 4));
+        description = ''
+          List of extra IPv4 static routes that will be assigned to the interface.
+        '';
+      };
+
+      ipv6Routes = mkOption {
+        default = [];
+        example = [
+          { address = "fdfd:b3f0::"; prefixLength = 48; }
+          { address = "2001:1470:fffd:2098::"; prefixLength = 64; nextHop = "fdfd:b3f0::1"; }
+        ];
+        type = with types; listOf (submodule (routeOpts 6));
+        description = ''
+          List of extra IPv6 static routes that will be assigned to the interface.
+        '';
+      };
+
       ipAddress = mkOption {
         default = null;
         example = "10.0.0.1";
@@ -1089,6 +1147,9 @@ in
           '' + optionalString (i.mtu != null) ''
             echo "setting MTU to ${toString i.mtu}..."
             ip link set "${i.name}" mtu "${toString i.mtu}"
+          '' + ''
+            echo -n "bringing up interface... "
+            ip link set "${i.name}" up && echo "done" || (echo "failed"; exit 1)
           '';
       })));