nixos/home: Migrate river WAN to PPPoE over Digiweb
river's WAN moves to a PPPoE session (Digiweb, over VLAN 10 with baby-jumbo 1508 MTU) driven by pppd, with its ip-up/ip-down hooks toggling a new wan-online.target. stream keeps its DHCP WAN, so the existing 50-wan / 50-wan-ifb networkd config moves out of routing-common into stream, and the shared consumers (ipsec, ipv6-clear-default-route) now attach to wan-online.target instead of depending on systemd-networkd-wait-online@wan directly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -312,6 +312,9 @@ rec {
|
|||||||
lo = 110;
|
lo = 110;
|
||||||
untrusted = 120;
|
untrusted = 120;
|
||||||
wan = 130;
|
wan = 130;
|
||||||
|
wan-pon = 131;
|
||||||
|
|
||||||
|
pon-isp = 10;
|
||||||
};
|
};
|
||||||
hiMTU = 9000;
|
hiMTU = 9000;
|
||||||
routers = [
|
routers = [
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
configuration = { lib, modulesPath, pkgs, config, assignments, allAssignments, ... }:
|
configuration = { lib, modulesPath, pkgs, config, assignments, allAssignments, ... }:
|
||||||
let
|
let
|
||||||
|
inherit (lib) mkForce mkMerge;
|
||||||
inherit (lib.my) networkdAssignment mkVLAN;
|
inherit (lib.my) networkdAssignment mkVLAN;
|
||||||
inherit (lib.my.c) networkd;
|
inherit (lib.my.c) networkd;
|
||||||
inherit (lib.my.c.home) vlans domain prefixes roceBootModules;
|
inherit (lib.my.c.home) vlans domain prefixes roceBootModules;
|
||||||
@@ -71,11 +72,72 @@
|
|||||||
dmeventd.enable = true;
|
dmeventd.enable = true;
|
||||||
};
|
};
|
||||||
fstrim.enable = true;
|
fstrim.enable = true;
|
||||||
|
|
||||||
|
# TODO: re-enable once scheduling is tested
|
||||||
|
networkd-dispatcher.enable = mkForce false;
|
||||||
|
|
||||||
|
pppd = {
|
||||||
|
enable = true;
|
||||||
|
peers.digiweb = {
|
||||||
|
autostart = true;
|
||||||
|
enable = true;
|
||||||
|
# Password is shared across all Digiweb customers, so no need for a secret
|
||||||
|
config = ''
|
||||||
|
plugin pppoe.so wan-vlan-inner
|
||||||
|
name "digiweb@nga.digiweb.ie"
|
||||||
|
password "digiweb"
|
||||||
|
noipdefault
|
||||||
|
# no usepeerdns: we ignore Digiweb's resolvers and use the local recursive resolver
|
||||||
|
lcp-echo-interval 1
|
||||||
|
lcp-echo-failure 4
|
||||||
|
noauth
|
||||||
|
persist
|
||||||
|
maxfail 0
|
||||||
|
holdoff 5
|
||||||
|
mtu 1500
|
||||||
|
mru 1500
|
||||||
|
noaccomp
|
||||||
|
default-asyncmap
|
||||||
|
ifname wan
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# PPPoE WAN (Digiweb): pppd owns the `wan` interface on top of VLAN 10, and its
|
||||||
|
# ip-up/ip-down hooks toggle the shared wan-online.target. Nothing else Wants the
|
||||||
|
# target, so it stays inactive until the link is actually up.
|
||||||
|
systemd.targets.wan-online.unitConfig.DefaultDependencies = false;
|
||||||
|
|
||||||
|
environment.etc = {
|
||||||
|
ppp-up = {
|
||||||
|
target = "ppp/ip-up";
|
||||||
|
mode = "0755";
|
||||||
|
text = ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
${pkgs.iproute2}/bin/ip route add default dev wan scope link metric 100
|
||||||
|
${config.systemd.package}/bin/systemctl --no-block start wan-online.target
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
ppp-down = {
|
||||||
|
target = "ppp/ip-down";
|
||||||
|
mode = "0755";
|
||||||
|
text = ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
${config.systemd.package}/bin/systemctl --no-block stop wan-online.target
|
||||||
|
${pkgs.iproute2}/bin/ip route del default dev wan scope link metric 100
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.network = {
|
systemd.network = {
|
||||||
|
netdevs = mkMerge [
|
||||||
|
(mkVLAN "wan-vlan-outer" vlans.wan-pon)
|
||||||
|
(mkVLAN "wan-vlan-inner" vlans.pon-isp)
|
||||||
|
];
|
||||||
|
|
||||||
links = {
|
links = {
|
||||||
"10-wan" = {
|
"10-wan-old" = {
|
||||||
matchConfig = {
|
matchConfig = {
|
||||||
# Matching against MAC address seems to break VLAN interfaces
|
# Matching against MAC address seems to break VLAN interfaces
|
||||||
# (since they share the same MAC address)
|
# (since they share the same MAC address)
|
||||||
@@ -83,7 +145,7 @@
|
|||||||
PermanentMACAddress = "e0:d5:5e:68:0c:6e";
|
PermanentMACAddress = "e0:d5:5e:68:0c:6e";
|
||||||
};
|
};
|
||||||
linkConfig = {
|
linkConfig = {
|
||||||
Name = "wan";
|
Name = "wan-old";
|
||||||
RxBufferSize = 4096;
|
RxBufferSize = 4096;
|
||||||
TxBufferSize = 4096;
|
TxBufferSize = 4096;
|
||||||
};
|
};
|
||||||
@@ -101,8 +163,31 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
networks = {
|
||||||
|
"55-lan" = {
|
||||||
|
vlan = [ "wan-vlan-outer" ];
|
||||||
|
};
|
||||||
# So we don't drop the IP we use to connect to NVMe-oF!
|
# So we don't drop the IP we use to connect to NVMe-oF!
|
||||||
networks."60-lan-hi".networkConfig.KeepConfiguration = "static";
|
"60-lan-hi".networkConfig.KeepConfiguration = "static";
|
||||||
|
|
||||||
|
"70-wan-vlan-outer" = {
|
||||||
|
matchConfig.Name = "wan-vlan-outer";
|
||||||
|
vlan = [ "wan-vlan-inner" ];
|
||||||
|
networkConfig = networkd.noL3;
|
||||||
|
# baby jumbo: 1508 so the inner VLAN below can also carry it
|
||||||
|
linkConfig.MTUBytes = "1508";
|
||||||
|
};
|
||||||
|
# pppd attaches PPPoE to this; just needs to be up with no L3
|
||||||
|
"71-wan-vlan-inner" = {
|
||||||
|
matchConfig.Name = "wan-vlan-inner";
|
||||||
|
linkConfig = {
|
||||||
|
RequiredForOnline = "no";
|
||||||
|
# baby jumbo: PPPoE's 8B overhead leaves a clean 1500 on ppp
|
||||||
|
MTUBytes = "1508";
|
||||||
|
};
|
||||||
|
networkConfig = networkd.noL3;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
my = {
|
my = {
|
||||||
|
|||||||
@@ -152,26 +152,29 @@ in
|
|||||||
|
|
||||||
networking = { inherit domain; };
|
networking = { inherit domain; };
|
||||||
|
|
||||||
systemd.services =
|
# Uniform "WAN is up" gate. Consumers attach to this target (via wantedBy +
|
||||||
let
|
# partOf) rather than depending on it, so it is never pulled in / prematurely
|
||||||
waitOnline = "systemd-networkd-wait-online@wan.service";
|
# activated. Each box wires up how the target actually gets reached: stream
|
||||||
in
|
# gates it on networkd's wait-online, river drives it from the pppd hooks.
|
||||||
{
|
systemd.targets.wan-online.description = "WAN is online";
|
||||||
|
|
||||||
|
systemd.services = {
|
||||||
ipsec = {
|
ipsec = {
|
||||||
after = [ waitOnline ];
|
after = [ "wan-online.target" ];
|
||||||
requires = [ waitOnline ];
|
wantedBy = [ "wan-online.target" ];
|
||||||
|
partOf = [ "wan-online.target" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
ipv6-clear-default-route = {
|
ipv6-clear-default-route = {
|
||||||
description = "Clear IPv6 RA default route";
|
description = "Clear IPv6 RA default route";
|
||||||
after = [ waitOnline ];
|
after = [ "wan-online.target" ];
|
||||||
requires = [ waitOnline ];
|
wantedBy = [ "wan-online.target" ];
|
||||||
|
partOf = [ "wan-online.target" ];
|
||||||
script = ''
|
script = ''
|
||||||
# Seems like we can sometimes pick up a default route somehow...
|
# Seems like we can sometimes pick up a default route somehow...
|
||||||
${pkgs.iproute2}/bin/ip -6 route del default via fe80::1 || true
|
${pkgs.iproute2}/bin/ip -6 route del default via fe80::1 || true
|
||||||
'';
|
'';
|
||||||
serviceConfig.Type = "oneshot";
|
serviceConfig.Type = "oneshot";
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -220,41 +223,6 @@ in
|
|||||||
in
|
in
|
||||||
mkMerge [
|
mkMerge [
|
||||||
{
|
{
|
||||||
"50-wan-ifb" = {
|
|
||||||
matchConfig.Name = "wan-ifb";
|
|
||||||
networkConfig = networkd.noL3;
|
|
||||||
extraConfig = ''
|
|
||||||
[CAKE]
|
|
||||||
Bandwidth=490M
|
|
||||||
RTTSec=50ms
|
|
||||||
PriorityQueueingPreset=besteffort
|
|
||||||
# DOCSIS preset
|
|
||||||
OverheadBytes=18
|
|
||||||
MPUBytes=64
|
|
||||||
CompensationMode=none
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"50-wan" = mkMerge [
|
|
||||||
(networkdAssignment "wan" assignments.modem)
|
|
||||||
{
|
|
||||||
matchConfig.Name = "wan";
|
|
||||||
DHCP = "ipv4";
|
|
||||||
dns = [ "127.0.0.1" "::1" ];
|
|
||||||
dhcpV4Config.UseDNS = false;
|
|
||||||
|
|
||||||
qdiscConfig = {
|
|
||||||
Parent = "ingress";
|
|
||||||
Handle = "0xffff";
|
|
||||||
};
|
|
||||||
extraConfig = ''
|
|
||||||
[CAKE]
|
|
||||||
Parent=root
|
|
||||||
Bandwidth=48M
|
|
||||||
RTTSec=50ms
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
"55-lan" = {
|
"55-lan" = {
|
||||||
matchConfig.Name = "lan";
|
matchConfig.Name = "lan";
|
||||||
vlan = [ "lan-hi" "lan-lo" "lan-untrusted" "wan-tunnel" ];
|
vlan = [ "lan-hi" "lan-lo" "lan-untrusted" "wan-tunnel" ];
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
nixpkgs = "mine";
|
nixpkgs = "mine";
|
||||||
home-manager = "mine";
|
home-manager = "mine";
|
||||||
|
|
||||||
configuration = { lib, pkgs, config, ... }:
|
configuration = { lib, pkgs, config, assignments, ... }:
|
||||||
let
|
let
|
||||||
inherit (lib);
|
inherit (lib) mkMerge;
|
||||||
|
inherit (lib.my) networkdAssignment;
|
||||||
|
inherit (lib.my.c) networkd;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ ./routing-common/mstpd.nix ];
|
imports = [ ./routing-common/mstpd.nix ];
|
||||||
@@ -75,6 +77,14 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# WAN is a plain networkd-managed DHCP link here; gate the shared wan-online
|
||||||
|
# target on networkd reporting it online.
|
||||||
|
systemd.targets.wan-online = {
|
||||||
|
requires = [ "systemd-networkd-wait-online@wan.service" ];
|
||||||
|
after = [ "systemd-networkd-wait-online@wan.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
systemd.network = {
|
systemd.network = {
|
||||||
netdevs = {
|
netdevs = {
|
||||||
"25-lan" = {
|
"25-lan" = {
|
||||||
@@ -147,6 +157,41 @@
|
|||||||
matchConfig.Name = "lan-dave";
|
matchConfig.Name = "lan-dave";
|
||||||
networkConfig.Bridge = "lan";
|
networkConfig.Bridge = "lan";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
"50-wan-ifb" = {
|
||||||
|
matchConfig.Name = "wan-ifb";
|
||||||
|
networkConfig = networkd.noL3;
|
||||||
|
extraConfig = ''
|
||||||
|
[CAKE]
|
||||||
|
Bandwidth=490M
|
||||||
|
RTTSec=50ms
|
||||||
|
PriorityQueueingPreset=besteffort
|
||||||
|
# DOCSIS preset
|
||||||
|
OverheadBytes=18
|
||||||
|
MPUBytes=64
|
||||||
|
CompensationMode=none
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"50-wan" = mkMerge [
|
||||||
|
(networkdAssignment "wan" assignments.modem)
|
||||||
|
{
|
||||||
|
matchConfig.Name = "wan";
|
||||||
|
DHCP = "ipv4";
|
||||||
|
dns = [ "127.0.0.1" "::1" ];
|
||||||
|
dhcpV4Config.UseDNS = false;
|
||||||
|
|
||||||
|
qdiscConfig = {
|
||||||
|
Parent = "ingress";
|
||||||
|
Handle = "0xffff";
|
||||||
|
};
|
||||||
|
extraConfig = ''
|
||||||
|
[CAKE]
|
||||||
|
Parent=root
|
||||||
|
Bandwidth=48M
|
||||||
|
RTTSec=50ms
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user