{ config, lib, pkgs, ... }: with lib; let pppInterface = config.networking.pppInterface; in { options = { networking.pppInterface = mkOption { type = types.str; default = "dsl"; }; }; config = { networking.vlans = { telekom = { id = 7; interface = "eno2"; }; }; services.pppd = { enable = true; peers.telekom.config = '' nodefaultroute ifname ${pppInterface} lcp-echo-adaptive lcp-echo-failure 5 lcp-echo-interval 1 maxfail 0 mtu 1492 mru 1492 plugin pppoe.so name telekom user 002576900250551137425220#0001@t-online.de telekom debug +ipv6 ''; }; systemd.services."pppd-telekom" = { stopIfChanged = true; serviceConfig = { PIDFile = "/run/pppd/${pppInterface}.pid"; }; }; sops.secrets."pap-secrets" = { format = "binary"; sopsFile = ./pap-secrets; path = "/etc/ppp/pap-secrets"; }; environment.etc = { "ppp/ip-pre-up".source = let app = pkgs.writeShellApplication { name = "ip-pre-up"; runtimeInputs = with pkgs; [ iproute2 ethtool ]; text = '' ethtool -K telekom tso off gso off gro off ip link del "ifb4${pppInterface}" || true ip link add name "ifb4${pppInterface}" type ifb ip link set "ifb4${pppInterface}" up tc qdisc del dev "ifb4${pppInterface}" root || true tc qdisc del dev "${pppInterface}" ingress || true tc qdisc del dev "${pppInterface}" root || true tc qdisc add dev "${pppInterface}" handle ffff: ingress tc filter add dev "${pppInterface}" parent ffff: basic action ctinfo dscp 0x0000003f 0x00000040 action mirred egress redirect dev "ifb4${pppInterface}" tc qdisc replace dev "ifb4${pppInterface}" root cake memlimit 64Mb pppoe-ptm diffserv4 bandwidth 93mbit tc qdisc replace dev "${pppInterface}" root cake memlimit 64Mb pppoe-ptm nat diffserv4 wash bandwidth 35mbit ''; }; in "${app}/bin/${app.meta.mainProgram}"; "ppp/ip-up".source = let app = pkgs.writeShellApplication { name = "ip-up"; runtimeInputs = with pkgs; [ iproute2 ]; text = '' ip route add default via "$5" dev "${pppInterface}" metric 512 ''; }; in "${app}/bin/${app.meta.mainProgram}"; "ppp/ip-down".source = let app = pkgs.writeShellApplication { name = "ip-down"; runtimeInputs = with pkgs; [ iproute2 ]; text = '' ip link del "ifb4${pppInterface}" ''; }; in "${app}/bin/${app.meta.mainProgram}"; }; systemd.network.networks.${pppInterface} = { matchConfig = { Name = pppInterface; }; dns = [ "::1" "127.0.0.1" ]; domains = [ "~." ]; networkConfig = { LinkLocalAddressing = "no"; DNSSEC = true; }; }; services.corerad = { enable = true; settings = { interfaces = [ { name = pppInterface; monitor = true; verbose = true; } { name = "lan"; advertise = true; verbose = true; prefix = [{ prefix = "::/64"; }]; route = [{ prefix = "::/0"; }]; rdnss = [{ servers = ["::"]; }]; dnssl = [{ domain_names = ["yggdrasil"]; }]; # other_config = true; } ]; debug = { address = "localhost:9430"; prometheus = true; }; }; }; services.ndppd = { enable = true; proxies = { ${pppInterface} = { router = true; rules = { lan = { method = "iface"; interface = "lan"; network = "::/0"; }; }; }; }; }; boot.kernelModules = [ "ifb" ]; boot.kernel.sysctl = { "net.ipv6.conf.all.forwarding" = true; "net.ipv6.conf.default.forwarding" = true; "net.ipv4.conf.all.forwarding" = true; "net.ipv4.conf.default.forwarding" = true; "net.core.rmem_max" = 4194304; "net.core.wmem_max" = 4194304; }; systemd.services."pppd-telekom" = { bindsTo = [ "sys-subsystem-net-devices-telekom.device" ]; after = [ "sys-subsystem-net-devices-telekom.device" ]; }; systemd.services."dhcpcd-${pppInterface}" = { wantedBy = [ "multi-user.target" "network-online.target" "pppd-telekom.service" ]; bindsTo = [ "pppd-telekom.service" ]; after = [ "pppd-telekom.service" ]; wants = [ "network.target" ]; before = [ "network-online.target" ]; path = with pkgs; [ dhcpcd nettools openresolv ]; unitConfig.ConditionCapability = "CAP_NET_ADMIN"; stopIfChanged = true; preStart = '' i=0 while [[ -z "$(${pkgs.iproute2}/bin/ip -6 addr show dev ${pppInterface} scope link)" ]]; do ${pkgs.coreutils}/bin/sleep 0.1 i=$((i + 1)) if [[ "$i" -ge 10 ]]; then exit 1 fi done ''; postStop = '' for dev in lan; do ${pkgs.iproute2}/bin/ip -6 a show dev "''${dev}" scope global | ${pkgs.gnugrep}/bin/grep inet6 | ${pkgs.gawk}/bin/awk '{ print $2; }' | ${pkgs.findutils}/bin/xargs -I '{}' -- ${pkgs.iproute2}/bin/ip addr del '{}' dev "''${dev}" done ''; serviceConfig = let dhcpcdConf = pkgs.writeText "dhcpcd.conf" '' duid vendorclassid ipv6only nooption domain_name_servers, domain_name, domain_search option classless_static_routes option interface_mtu option host_name option rapid_commit require dhcp_server_identifier slaac private nohook resolv.conf ipv6ra_autoconf iaid 1195061668 ipv6rs # enable routing solicitation for WAN adapter ia_pd 1 lan/0/64/0 # request a PD and assign it to the LAN reboot 0 waitip 6 ''; in { Type = "forking"; PIDFile = "/var/run/dhcpcd/${pppInterface}.pid"; RuntimeDirectory = "dhcpcd"; ExecStart = "@${pkgs.dhcpcd}/sbin/dhcpcd dhcpcd -q --config ${dhcpcdConf} ${pppInterface}"; ExecReload = "${pkgs.dhcpcd}/sbin/dhcpcd --rebind ${pppInterface}"; Restart = "always"; RestartSec = "5"; }; }; systemd.services.ndppd = { wantedBy = [ "dhcpcd-${pppInterface}.service" ]; bindsTo = [ "dhcpcd-${pppInterface}.service" ]; after = [ "dhcpcd-${pppInterface}.service" ]; serviceConfig = { Restart = "always"; RestartSec = "5"; }; }; systemd.services.corerad = { wantedBy = [ "dhcpcd-${pppInterface}.service" ]; bindsTo = [ "dhcpcd-${pppInterface}.service" ]; after = [ "dhcpcd-${pppInterface}.service" ]; serviceConfig = { Restart = lib.mkForce "always"; RestartSec = "5"; }; }; users.users.dhcpcd = { isSystemUser = true; group = "dhcpcd"; }; users.groups.dhcpcd = {}; systemd.services.unbound = { wantedBy = [ "dhcpcd-${pppInterface}.service" ]; bindsTo = [ "dhcpcd-${pppInterface}.service" ]; after = [ "dhcpcd-${pppInterface}.service" ]; serviceConfig = { Restart = lib.mkForce "always"; }; }; }; }