Add the home gateway config and tunnel source addresses

- wireguard.<n>.sourceAddresses: source for router-originated traffic
  into a tunnel without an address of its own (PreferredSource on the
  routes); checked at build time.
- examples/home: antigua's routing role ported to the router module
  (PPPoE with IPv6 inside the session, LAN with ULA and reservation,
  local DNS and forward zones, the freifunk/family/mobile tunnels with
  explicit zone rules, ddclient following the PPP device).
  nixosConfigurations.home, packages.installer-home and a flake check
  that builds it.
- PLAN.md: the remaining antigua gaps and the open question about
  services that stay behind the router.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-28 16:53:14 +01:00
co-authored by Claude Sonnet 5.5
parent c395a43a78
commit 406196adce
8 changed files with 322 additions and 5 deletions
+22
View File
@@ -380,6 +380,28 @@ let
assertion = lib.stringLength w.interface <= 15;
message = "router: ${where}: device name `${w.interface}` is longer than 15 characters.";
}
{
assertion = lib.all anyIp w.sourceAddresses;
message = "router: ${where}.sourceAddresses must be IPv4/IPv6 addresses.";
}
{
assertion =
lib.length (lib.filter isV6 w.sourceAddresses) <= 1
&& lib.length (lib.filter (s: !isV6 s) w.sourceAddresses) <= 1;
message = "router: ${where}.sourceAddresses may hold at most one address per family.";
}
{
assertion = lib.all (
s:
isV6 s
|| !(validIp s)
|| lib.elem s (
map (l: l.ipv4.address) lans
++ map (a: builtins.head (lib.splitString "/" a)) (lib.concatMap (x: x.addresses) wgs)
)
) w.sourceAddresses;
message = "router: ${where}.sourceAddresses: an IPv4 source must be the router's address on a LAN or a tunnel.";
}
{
assertion = lib.all validCidr w.addresses;
message = "router: ${where}.addresses must be IPv4/IPv6 addresses in CIDR notation.";