diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix
index 63d07832d10..9dba6d1bd0a 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
- 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 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 (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 f80c5045c07..d437a829be5 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 (${if v == 4 then "24" else "64"}).
+ '';
+ };
+
+ 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 OPTION
+ in the ip-route(8) 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)
'';
})));