# SPDX-FileCopyrightText: 2023-2024 Simon Bruder # # 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"; avahi = true; }; management = { id = 20; subnet = mkSubnet "10.80.2.0/24" "2001:470:73b9:2::/64"; domain = "management.shinonome-lab.de"; avahi = false; }; guest = { id = 30; subnet = mkSubnet "10.80.3.0/24" "2001:470:73b9:3::/64"; domain = "guest.shinonome-lab.de"; avahi = false; }; iot = { id = 40; subnet = mkSubnet "10.80.4.0/24" "2001:470:73b9:4::/64"; domain = "iot.shinonome-lab.de"; avahi = true; }; printer = { id = 41; subnet = mkSubnet "10.80.5.0/24" "2001:470:73b9:5::/64"; domain = "printer.shinonome-lab.de"; avahi = true; }; }; 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"; }; }; }