nixos/networking-interfaces: make static routes configurable

rnhmjoj d00c91c5 05f5cdcf

Changed files
+107 -22
nixos
+45 -21
nixos/modules/tasks/network-interfaces-scripted.nix
···
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")
-
state="/run/nixos/network/addresses/${i.name}"
+
${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"
'';
+62 -1
nixos/modules/tasks/network-interfaces.nix
···
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.
'';
};
···
};
};
};
+
+
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; };
···
type = with types; listOf (submodule (addrOpts 6));
description = ''
List of IPv6 addresses that will be statically assigned to the interface.
+
'';
+
};
+
+
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.
'';
};
···
'' + 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)
'';
})));