Simon Bruder
b55cc2deaf
This is required to have them available in nftables rules without too much headache.
161 lines
3.7 KiB
Nix
161 lines
3.7 KiB
Nix
# SPDX-FileCopyrightText: 2023-2024 Simon Bruder <simon@sbruder.de>
|
||
#
|
||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||
|
||
{ lib, ... }:
|
||
let
|
||
mkSubnet = v4: v6:
|
||
let
|
||
splitCidr = lib.splitString "/";
|
||
fst = lib.flip lib.elemAt 0;
|
||
snd = lib.flip lib.elemAt 1;
|
||
|
||
v4Split = splitCidr v4;
|
||
v6Split = splitCidr v6;
|
||
in
|
||
{
|
||
v4 = rec {
|
||
cidr = v4;
|
||
net = fst v4Split;
|
||
suffix = snd v4Split;
|
||
withoutLastComponent = lib.substring 0 ((lib.stringLength net) - 1) net;
|
||
gateway = "${withoutLastComponent}1";
|
||
gatewayCidr = "${gateway}/${suffix}";
|
||
};
|
||
v6 = rec {
|
||
cidr = v6;
|
||
net = fst v6Split;
|
||
suffix = snd v6Split;
|
||
withoutLocalComponent = lib.substring 0 ((lib.stringLength net) - 1) net;
|
||
gateway = "${net}1";
|
||
gatewayCidr = "${gateway}/${suffix}";
|
||
};
|
||
};
|
||
|
||
macToIpv6InterfaceIdentifier = mac:
|
||
let
|
||
macList = lib.splitString ":" mac;
|
||
macListIpv6 = lib.flatten [
|
||
(lib.toHexString (lib.bitXor (builtins.fromTOML "x = 0x${lib.elemAt macList 0}").x 2))
|
||
(lib.sublist 1 2 macList)
|
||
[ "ff" "fe" ]
|
||
(lib.sublist 3 3 macList)
|
||
];
|
||
interfaceIdentifierNoColons = lib.strings.toLower (lib.concatStrings macListIpv6);
|
||
interfaceIdentifier = lib.concatStrings [
|
||
(lib.substring 0 4 interfaceIdentifierNoColons)
|
||
":"
|
||
(lib.substring 4 4 interfaceIdentifierNoColons)
|
||
":"
|
||
(lib.substring 8 4 interfaceIdentifierNoColons)
|
||
":"
|
||
(lib.substring 12 4 interfaceIdentifierNoColons)
|
||
];
|
||
in
|
||
interfaceIdentifier;
|
||
in
|
||
rec {
|
||
vlan = {
|
||
lan = {
|
||
id = 10;
|
||
subnet = mkSubnet "10.80.1.0/24" "2001:470:73b9:1::/64";
|
||
domain = "lan.shinonome-lab.de";
|
||
};
|
||
management = {
|
||
id = 20;
|
||
subnet = mkSubnet "10.80.2.0/24" "2001:470:73b9:2::/64";
|
||
domain = "management.shinonome-lab.de";
|
||
};
|
||
guest = {
|
||
id = 30;
|
||
subnet = mkSubnet "10.80.3.0/24" "2001:470:73b9:3::/64";
|
||
domain = "guest.shinonome-lab.de";
|
||
};
|
||
iot = {
|
||
id = 40;
|
||
subnet = mkSubnet "10.80.4.0/24" "2001:470:73b9:4::/64";
|
||
domain = "iot.shinonome-lab.de";
|
||
};
|
||
};
|
||
tc = {
|
||
interface = "enp1s0";
|
||
# 4160 kbit is slightly smaller than the average upload
|
||
rate = "4160kbit";
|
||
major = 1;
|
||
default = 2;
|
||
classes = [
|
||
# default
|
||
{
|
||
minor = 2;
|
||
rate = "800kbit";
|
||
prio = 50;
|
||
}
|
||
# DNS, small packets (e.g., TCP ACK)
|
||
{
|
||
minor = 3;
|
||
rate = "250kbit";
|
||
prio = 0;
|
||
qdiscArgs = [ "pfifo_fast" ];
|
||
}
|
||
# interactive SSH
|
||
{
|
||
minor = 4;
|
||
rate = "128kbit";
|
||
prio = 2;
|
||
}
|
||
# torrent
|
||
{
|
||
minor = 5;
|
||
rate = "250kbit";
|
||
ceil = "3000kbit";
|
||
prio = 100;
|
||
}
|
||
# HTTP
|
||
{
|
||
minor = 6;
|
||
rate = "1500kbit";
|
||
prio = 25;
|
||
}
|
||
# wg-home
|
||
{
|
||
minor = 7;
|
||
rate = "250kbit";
|
||
prio = 10;
|
||
}
|
||
# VoIP
|
||
{
|
||
minor = 8;
|
||
rate = "256kbit";
|
||
ceil = "384kbit";
|
||
prio = 3;
|
||
qdiscArgs = [ "pfifo_fast" ];
|
||
}
|
||
# Backup
|
||
{
|
||
minor = 9;
|
||
rate = "350kbit";
|
||
ceil = "3000kbit";
|
||
prio = 90;
|
||
}
|
||
# guest
|
||
{
|
||
minor = 10;
|
||
rate = "200kbit";
|
||
ceil = "2000kbit";
|
||
prio = 99;
|
||
}
|
||
];
|
||
};
|
||
staticHosts = lib.mapAttrs
|
||
(_: options: options // {
|
||
address6 = "${vlan.${options.vlan}.subnet.v6.withoutLocalComponent}${macToIpv6InterfaceIdentifier options.hwaddr}";
|
||
})
|
||
{
|
||
fuuko = {
|
||
hwaddr = "18:c0:4d:d2:93:f0";
|
||
address4 = "10.80.1.98";
|
||
vlan = "lan";
|
||
};
|
||
};
|
||
}
|