2021-04-01 01:16:13 +02:00
|
|
|
{ hostName, config, lib, ... }:
|
|
|
|
|
|
|
|
let
|
2021-05-01 01:14:54 +02:00
|
|
|
hostConf = config.site.hosts.${hostName};
|
|
|
|
|
2021-04-01 01:16:13 +02:00
|
|
|
upstreamInterfaces =
|
|
|
|
lib.filterAttrs (_: { upstream, ... }: upstream != null)
|
2021-05-01 01:14:54 +02:00
|
|
|
hostConf.interfaces;
|
2021-04-08 01:48:40 +02:00
|
|
|
|
2021-04-01 01:16:13 +02:00
|
|
|
firstUpstreamInterface =
|
|
|
|
if builtins.length (builtins.attrNames upstreamInterfaces) > 0
|
|
|
|
then builtins.head (
|
|
|
|
builtins.attrNames upstreamInterfaces
|
|
|
|
)
|
|
|
|
else null;
|
2021-04-08 01:48:40 +02:00
|
|
|
|
2021-09-06 22:08:15 +02:00
|
|
|
enabled = firstUpstreamInterface != null;
|
2021-04-01 01:16:13 +02:00
|
|
|
in
|
|
|
|
{
|
2021-04-08 01:43:02 +02:00
|
|
|
systemd.network.networks = {
|
|
|
|
core = {
|
|
|
|
# systemd-networkd only requests Prefix Delegation via DHCPv6 on
|
|
|
|
# the upstream interface if another interface is configured for it.
|
|
|
|
# without this, the static ipv6 subnet won't be routed to us.
|
2021-04-29 01:34:33 +02:00
|
|
|
networkConfig.DHCPv6PrefixDelegation = true;
|
2021-04-08 01:43:02 +02:00
|
|
|
dhcpV6PrefixDelegationConfig = {
|
|
|
|
SubnetId = "81";
|
|
|
|
# because we have static addresses, we don't actually use this
|
|
|
|
Assign = false;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
} // builtins.mapAttrs (_: { upstream, ... }: {
|
2021-04-01 01:16:13 +02:00
|
|
|
DHCP = "yes";
|
2021-04-08 01:43:02 +02:00
|
|
|
networkConfig.IPv6AcceptRA = true;
|
|
|
|
dhcpV6Config.PrefixDelegationHint = "::/56";
|
2021-04-03 04:31:55 +02:00
|
|
|
|
2021-04-08 01:48:40 +02:00
|
|
|
# Traffic Shaping
|
2021-04-03 04:31:55 +02:00
|
|
|
extraConfig = ''
|
|
|
|
[CAKE]
|
|
|
|
Parent = root
|
2021-05-31 00:41:38 +02:00
|
|
|
${lib.optionalString (upstream.provider == "vodafone") ''
|
|
|
|
# DOCSIS overhead
|
|
|
|
OverheadBytes = 18
|
|
|
|
''}
|
|
|
|
${lib.optionalString (upstream.provider == "dsi") ''
|
|
|
|
# PPPoE overhead
|
|
|
|
OverheadBytes = 18
|
|
|
|
''}
|
2021-05-22 01:19:16 +02:00
|
|
|
${lib.optionalString (upstream.upBandwidth != null) ''
|
|
|
|
Bandwidth = ${toString upstream.upBandwidth}K
|
|
|
|
''}
|
2021-04-03 04:31:55 +02:00
|
|
|
'';
|
2021-04-01 01:16:13 +02:00
|
|
|
}) upstreamInterfaces;
|
|
|
|
|
2021-04-08 01:48:40 +02:00
|
|
|
networking.nat = lib.optionalAttrs enabled {
|
2021-04-01 01:16:13 +02:00
|
|
|
enable = true;
|
2021-04-06 22:59:51 +02:00
|
|
|
internalInterfaces = [ "core" ];
|
2021-04-01 01:16:13 +02:00
|
|
|
externalInterface = firstUpstreamInterface;
|
2021-09-06 23:17:46 +02:00
|
|
|
externalIP = upstreamInterfaces.${firstUpstreamInterface}.upstream.staticIpv4Address;
|
2021-05-01 01:14:54 +02:00
|
|
|
extraCommands =
|
2021-09-06 22:08:15 +02:00
|
|
|
# Provide IPv6 upstream for everyone, using NAT66 when not from
|
|
|
|
# our static prefixes
|
2021-09-06 23:41:45 +02:00
|
|
|
lib.concatMapStringsSep "\n" (net: ''
|
|
|
|
ip6tables -t nat -N ${net}_nat || \
|
|
|
|
ip6tables -t nat -F ${net}_nat
|
|
|
|
${lib.concatMapStringsSep "\n" (subnet: ''
|
|
|
|
ip6tables -t nat -A ${net}_nat \
|
|
|
|
-s ${subnet} \
|
|
|
|
-j RETURN
|
|
|
|
'') upstreamInterfaces.${net}.upstream.noNat.subnets6}
|
|
|
|
ip6tables -t nat -A ${net}_nat -j MASQUERADE
|
2021-05-01 01:14:54 +02:00
|
|
|
|
2021-09-06 23:41:45 +02:00
|
|
|
ip6tables -t nat -A POSTROUTING \
|
|
|
|
-o ${net} \
|
|
|
|
-j ${net}_nat
|
|
|
|
'') (builtins.attrNames upstreamInterfaces);
|
2021-05-14 18:37:45 +02:00
|
|
|
extraStopCommands =
|
2021-09-06 23:41:45 +02:00
|
|
|
lib.concatMapStringsSep "\n" (net: ''
|
|
|
|
ip6tables -t nat -F POSTROUTING 2>/dev/null || true
|
|
|
|
ip6tables -t nat -F ${net}_nat 2>/dev/null || true
|
|
|
|
ip6tables -t nat -X ${net}_nat 2>/dev/null || true
|
|
|
|
'') (builtins.attrNames upstreamInterfaces);
|
|
|
|
|
|
|
|
forwardPorts = map ({ destination, sourcePort, ... }@forwardedPort:
|
|
|
|
forwardedPort // {
|
|
|
|
destination =
|
|
|
|
if builtins.match ".*:.*" destination != null
|
|
|
|
then destination
|
|
|
|
else "${destination}:${toString sourcePort}";
|
|
|
|
loopbackIPs = builtins.filter (ip: ip != null) (
|
|
|
|
map (net:
|
|
|
|
upstreamInterfaces.${net}.upstream.staticIpv4Address
|
|
|
|
) (builtins.attrNames upstreamInterfaces)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
) hostConf.forwardPorts;
|
2021-04-01 01:16:13 +02:00
|
|
|
};
|
|
|
|
}
|