nixos/home/routing-common: Working IPv6 router

This commit is contained in:
Jack O'Sullivan 2023-12-16 15:59:33 +00:00
parent 8b0db3ac7f
commit 70f49c8438
11 changed files with 123 additions and 61 deletions

View File

@ -180,14 +180,17 @@ rec {
hi = { hi = {
v4 = subnet 4 1 all.v4; v4 = subnet 4 1 all.v4;
v6 = subnet 4 1 all.v6; v6 = subnet 4 1 all.v6;
mtu = hiMTU;
}; };
lo = { lo = {
v4 = subnet 3 1 all.v4; v4 = subnet 3 1 all.v4;
v6 = subnet 4 2 all.v6; v6 = subnet 4 2 all.v6;
mtu = 1500;
}; };
untrusted = { untrusted = {
v4 = subnet 6 16 all.v4; v4 = subnet 6 16 all.v4;
v6 = subnet 4 3 all.v6; v6 = subnet 4 3 all.v6;
mtu = 1500;
}; };
inherit (colony.prefixes) as211024; inherit (colony.prefixes) as211024;
}; };

View File

@ -4,7 +4,7 @@ let
inherit (lib) inherit (lib)
genAttrs mapAttrsToList filterAttrsRecursive nameValuePair types genAttrs mapAttrsToList filterAttrsRecursive nameValuePair types
mkOption mkOverride mkForce mkIf mergeEqualOption optional mkOption mkOverride mkForce mkIf mergeEqualOption optional
showWarnings concatStringsSep flatten unique; showWarnings concatStringsSep flatten unique optionalAttrs;
inherit (lib.flake) defaultSystems; inherit (lib.flake) defaultSystems;
in in
rec { rec {
@ -152,6 +152,9 @@ rec {
LLDP = true; LLDP = true;
EmitLLDP = "customer-bridge"; EmitLLDP = "customer-bridge";
}; };
linkConfig = optionalAttrs (a.mtu != null) {
MTUBytes = toString a.mtu;
};
ipv6AcceptRAConfig = { ipv6AcceptRAConfig = {
Token = mkIf (a.ipv6.iid != null) "static:${a.ipv6.iid}"; Token = mkIf (a.ipv6.iid != null) "static:${a.ipv6.iid}";
UseDNS = true; UseDNS = true;

View File

@ -17,6 +17,10 @@ in
mask = 22; mask = 22;
gateway = null; gateway = null;
}; };
ipv6 = {
iid = "::3:1";
address = net.cidr.host (65536*3+1) prefixes.hi.v6;
};
}; };
lo = { lo = {
inherit domain; inherit domain;
@ -25,6 +29,10 @@ in
mask = 21; mask = 21;
gateway = null; gateway = null;
}; };
ipv6 = {
iid = "::3:1";
address = net.cidr.host (65536*3+1) prefixes.lo.v6;
};
}; };
}; };

View File

@ -2,7 +2,7 @@
let let
inherit (lib.my) net mkVLAN; inherit (lib.my) net mkVLAN;
inherit (lib.my.c) pubDomain; inherit (lib.my.c) pubDomain;
inherit (lib.my.c.home) domain vlans prefixes vips; inherit (lib.my.c.home) domain vlans prefixes vips hiMTU;
in in
{ {
imports = [ ./vms ]; imports = [ ./vms ];
@ -15,15 +15,21 @@ in
assignments = { assignments = {
hi = { hi = {
inherit domain; inherit domain;
mtu = hiMTU;
ipv4 = { ipv4 = {
address = net.cidr.host 22 prefixes.hi.v4; address = net.cidr.host 22 prefixes.hi.v4;
mask = 22; mask = 22;
gateway = vips.hi.v4; gateway = vips.hi.v4;
}; };
ipv6 = {
iid = "::2:1";
address = net.cidr.host (65536*2+1) prefixes.hi.v6;
};
}; };
core = { core = {
inherit domain; inherit domain;
name = "palace-core"; name = "palace-core";
mtu = 1500;
ipv4 = { ipv4 = {
address = net.cidr.host 20 prefixes.core.v4; address = net.cidr.host 20 prefixes.core.v4;
gateway = null; gateway = null;
@ -131,7 +137,7 @@ in
}; };
linkConfig = { linkConfig = {
Name = "et100g"; Name = "et100g";
MTUBytes = "9000"; MTUBytes = toString hiMTU;
}; };
}; };
}; };
@ -169,17 +175,7 @@ in
MACAddress=52:54:00:8a:8a:f2 MACAddress=52:54:00:8a:8a:f2
''; '';
}; };
"60-lan-hi" = mkMerge [ "60-lan-hi" = networkdAssignment "lan-hi" assignments.hi;
(networkdAssignment "lan-hi" assignments.hi)
{
matchConfig.Name = "lan-hi";
linkConfig.MTUBytes = "9000";
networkConfig.DNS = [
(allAssignments.stream.hi.ipv4.address)
# (allAssignments.river.hi.ipv4.address)
];
}
];
}; };
}; };
}; };

View File

@ -2,7 +2,7 @@
let let
inherit (lib.my) net; inherit (lib.my) net;
inherit (lib.my.c) pubDomain; inherit (lib.my.c) pubDomain;
inherit (lib.my.c.home) domain prefixes vips; inherit (lib.my.c.home) domain prefixes vips hiMTU;
in in
{ {
nixos.systems.cellar = { nixos.systems.cellar = {
@ -12,11 +12,16 @@ in
assignments = { assignments = {
hi = { hi = {
inherit domain; inherit domain;
mtu = hiMTU;
ipv4 = { ipv4 = {
address = net.cidr.host 80 prefixes.hi.v4; address = net.cidr.host 80 prefixes.hi.v4;
mask = 22; mask = 22;
gateway = vips.hi.v4; gateway = vips.hi.v4;
}; };
ipv6 = {
iid = "::4:1";
address = net.cidr.host (65536*4+1) prefixes.hi.v6;
};
}; };
}; };
@ -66,23 +71,12 @@ in
links = { links = {
"10-lan-hi" = { "10-lan-hi" = {
matchConfig.PermanentMACAddress = "52:54:00:cc:3e:70"; matchConfig.PermanentMACAddress = "52:54:00:cc:3e:70";
linkConfig = { linkConfig.Name = "lan-hi";
Name = "lan-hi";
MTUBytes = "9000";
};
}; };
}; };
networks = { networks = {
"80-vms" = mkMerge [ "80-lan-hi" = networkdAssignment "lan-hi" assignments.hi;
(networkdAssignment "lan-hi" assignments.hi)
{
networkConfig.DNS = [
(allAssignments.stream.hi.ipv4.address)
(allAssignments.river.hi.ipv4.address)
];
}
];
}; };
}; };

View File

@ -3,7 +3,7 @@ let
inherit (builtins) elemAt; inherit (builtins) elemAt;
inherit (lib.my) net mkVLAN; inherit (lib.my) net mkVLAN;
inherit (lib.my.c) pubDomain; inherit (lib.my.c) pubDomain;
inherit (lib.my.c.home) domain vlans prefixes routers routersPubV4; inherit (lib.my.c.home) domain vlans prefixes vips routers routersPubV4;
name = elemAt routers index; name = elemAt routers index;
otherIndex = 1 - index; otherIndex = 1 - index;
@ -20,14 +20,16 @@ in
core = { core = {
name = "${name}-core"; name = "${name}-core";
inherit domain; inherit domain;
mtu = 1500;
ipv4 = { ipv4 = {
address = net.cidr.host (index + 1) prefixes.core.v4; address = net.cidr.host (index + 1) prefixes.core.v4;
gateway = null; gateway = null;
}; };
}; };
hi = { hi = {
inherit domain;
name = "${name}-hi"; name = "${name}-hi";
inherit domain;
mtu = 9000;
ipv4 = { ipv4 = {
address = net.cidr.host (index + 1) prefixes.hi.v4; address = net.cidr.host (index + 1) prefixes.hi.v4;
mask = 22; mask = 22;
@ -38,6 +40,7 @@ in
lo = { lo = {
name = "${name}-lo"; name = "${name}-lo";
inherit domain; inherit domain;
mtu = 1500;
ipv4 = { ipv4 = {
address = net.cidr.host (index + 1) prefixes.lo.v4; address = net.cidr.host (index + 1) prefixes.lo.v4;
mask = 21; mask = 21;
@ -48,6 +51,7 @@ in
untrusted = { untrusted = {
name = "${name}-ut"; name = "${name}-ut";
inherit domain; inherit domain;
mtu = 1500;
ipv4 = { ipv4 = {
address = net.cidr.host (index + 1) prefixes.untrusted.v4; address = net.cidr.host (index + 1) prefixes.untrusted.v4;
mask = 24; mask = 24;
@ -67,6 +71,33 @@ in
}; };
}; };
extraAssignments = {
router-hi.hi = {
name = "router-hi";
inherit domain;
ipv4 = {
address = vips.hi.v4;
mask = 22;
};
ipv6.address = vips.hi.v6;
};
router-lo.lo = {
name = "router-lo";
inherit domain;
ipv4 = {
address = vips.lo.v4;
mask = 21;
};
ipv6.address = vips.lo.v6;
};
router-ut.untrusted = {
name = "router-ut";
inherit domain;
ipv4.address = vips.untrusted.v4;
ipv6.address = vips.untrusted.v6;
};
};
configuration = { lib, pkgs, config, assignments, allAssignments, ... }: configuration = { lib, pkgs, config, assignments, allAssignments, ... }:
let let
inherit (lib) mkIf mkMerge mkForce; inherit (lib) mkIf mkMerge mkForce;
@ -77,6 +108,7 @@ in
imports = map (m: import m index) [ imports = map (m: import m index) [
./keepalived.nix ./keepalived.nix
./dns.nix ./dns.nix
./radvd.nix
]; ];
config = { config = {
@ -158,7 +190,7 @@ in
networks = networks =
let let
mkVLANConfig = name: mtu: mkVLANConfig = name:
let let
iface = "lan-${name}"; iface = "lan-${name}";
in in
@ -166,26 +198,9 @@ in
"60-${iface}" = mkMerge [ "60-${iface}" = mkMerge [
(networkdAssignment iface assignments."${name}") (networkdAssignment iface assignments."${name}")
{ {
linkConfig.MTUBytes = toString mtu; dns = [ "127.0.0.1" "::1" ];
domains = [ config.networking.domain ]; domains = [ config.networking.domain ];
networkConfig = { networkConfig.IPv6AcceptRA = mkForce false;
IPv6AcceptRA = mkForce false;
# IPv6SendRA = true;
};
ipv6SendRAConfig = {
DNS = [
(net.cidr.host 1 prefixes."${name}".v4)
(net.cidr.host 2 prefixes."${name}".v4)
(net.cidr.host 1 prefixes."${name}".v6)
(net.cidr.host 2 prefixes."${name}".v6)
];
Domains = [ config.networking.domain ];
};
ipv6Prefixes = [
{
ipv6PrefixConfig.Prefix = prefixes."${name}".v6;
}
];
} }
]; ];
}; };
@ -256,9 +271,9 @@ in
]; ];
} }
(mkVLANConfig "hi" 9000) (mkVLANConfig "hi")
(mkVLANConfig "lo" 1500) (mkVLANConfig "lo")
(mkVLANConfig "untrusted" 1500) (mkVLANConfig "untrusted")
{ {
"60-lan-hi" = { "60-lan-hi" = {

View File

@ -102,7 +102,7 @@ in
bind.zones = bind.zones =
let let
names = [ "core" "hi" "lo" ]; names = [ "core" "hi" "lo" "untrusted" ];
i = toString (index + 1); i = toString (index + 1);
in in
{ {
@ -138,11 +138,15 @@ in
jim-core IN A ${net.cidr.host 10 prefixes.core.v4} jim-core IN A ${net.cidr.host 10 prefixes.core.v4}
jim IN A ${net.cidr.host 10 prefixes.hi.v4} jim IN A ${net.cidr.host 10 prefixes.hi.v4}
jim IN AAAA ${net.cidr.host (65536+1) prefixes.hi.v6}
jim-lo IN A ${net.cidr.host 10 prefixes.lo.v4} jim-lo IN A ${net.cidr.host 10 prefixes.lo.v4}
jim-lo IN AAAA ${net.cidr.host (65536+1) prefixes.lo.v6}
dave-core IN A ${net.cidr.host 11 prefixes.core.v4} dave-core IN A ${net.cidr.host 11 prefixes.core.v4}
dave IN A ${net.cidr.host 11 prefixes.hi.v4} dave IN A ${net.cidr.host 11 prefixes.hi.v4}
dave IN AAAA ${net.cidr.host (65536+2) prefixes.hi.v6}
dave-lo IN A ${net.cidr.host 11 prefixes.lo.v4} dave-lo IN A ${net.cidr.host 11 prefixes.lo.v4}
dave-lo IN AAAA ${net.cidr.host (65536+2) prefixes.lo.v6}
ups IN A ${net.cidr.host 20 prefixes.lo.v4} ups IN A ${net.cidr.host 20 prefixes.lo.v4}
palace-kvm IN A ${net.cidr.host 21 prefixes.lo.v4} palace-kvm IN A ${net.cidr.host 21 prefixes.lo.v4}

View File

@ -1,20 +1,30 @@
index: { lib, pkgs, ... }: index: { lib, pkgs, config, ... }:
let let
inherit (builtins) attrNames; inherit (builtins) attrNames concatMap;
inherit (lib) optional;
inherit (lib.my) net; inherit (lib.my) net;
inherit (lib.my.c.home) prefixes vips; inherit (lib.my.c.home) prefixes vips;
vlanIface = vlan: if vlan == "as211024" then vlan else "lan-${vlan}"; vlanIface = vlan: if vlan == "as211024" then vlan else "lan-${vlan}";
vrrpIPs = family: map (vlan: { vrrpIPs = family: concatMap (vlan: [
addr = "${vips.${vlan}.${family}}/${toString (net.cidr.length prefixes.${vlan}.${family})}"; {
addr = "${vips.${vlan}.${family}}/${toString (net.cidr.length prefixes.${vlan}.${family})}";
dev = vlanIface vlan;
}
] ++ (optional (family == "v6") {
addr = "fe80::1/64";
dev = vlanIface vlan; dev = vlanIface vlan;
}) (attrNames vips); })) (attrNames vips);
mkVRRP = family: routerId: { mkVRRP = family: routerId: {
state = if index == 0 then "MASTER" else "BACKUP"; state = if index == 0 then "MASTER" else "BACKUP";
interface = "lan-core"; interface = "lan-core";
priority = 255 - index; priority = 255 - index;
virtualRouterId = routerId; virtualRouterId = routerId;
virtualIps = vrrpIPs family; virtualIps = vrrpIPs family;
extraConfig = ''
notify_master "${config.systemd.package}/bin/systemctl start radvd.service"
notify_backup "${config.systemd.package}/bin/systemctl stop radvd.service"
'';
}; };
in in
{ {

View File

@ -0,0 +1,28 @@
index: { lib, pkgs, ... }:
let
inherit (lib) mkForce concatMapStringsSep;
inherit (lib.my) net;
inherit (lib.my.c.home) domain prefixes;
mkInterface = name: ''
interface lan-${name} {
AdvSendAdvert on;
AdvRASrcAddress { fe80::1; };
AdvLinkMTU ${toString prefixes."${name}".mtu};
prefix ${prefixes."${name}".v6} {};
RDNSS ${net.cidr.host 1 prefixes."${name}".v6} ${net.cidr.host 2 prefixes."${name}".v6} {};
DNSSL ${domain} {};
};
'';
in
{
# To be started by keepalived
systemd.services.radvd.wantedBy = mkForce [ ];
services = {
radvd = {
enable = true;
config = concatMapStringsSep "\n" mkInterface [ "hi" "lo" "untrusted" ];
};
};
}

View File

@ -100,6 +100,7 @@ let
altNames = mkOpt' (listOf str) [ ] "Extra names to assign."; altNames = mkOpt' (listOf str) [ ] "Extra names to assign.";
visible = mkBoolOpt' true "Whether or not this assignment should be visible."; visible = mkBoolOpt' true "Whether or not this assignment should be visible.";
domain = mkOpt' (nullOr str) null "Domain for this assignment."; domain = mkOpt' (nullOr str) null "Domain for this assignment.";
mtu = mkOpt' (nullOr ints.unsigned) null "Interface MTU.";
ipv4 = { ipv4 = {
address = mkOpt' net.types.ipv4 null "IPv4 address."; address = mkOpt' net.types.ipv4 null "IPv4 address.";
mask = mkOpt' ints.u8 24 "Network mask."; mask = mkOpt' ints.u8 24 "Network mask.";

View File

@ -1,7 +1,7 @@
{ lib, pkgs, config, ... }: { lib, pkgs, config, ... }:
let let
inherit (builtins) toJSON; inherit (builtins) toJSON;
inherit (lib) optional mapAttrsToList mkIf withFeature; inherit (lib) optional optionalAttrs mapAttrsToList mkIf withFeature;
inherit (lib.my) mkOpt' mkBoolOpt'; inherit (lib.my) mkOpt' mkBoolOpt';
rpcOpts = with lib.types; { rpcOpts = with lib.types; {
@ -17,7 +17,7 @@ let
inherit subsystem; inherit subsystem;
config = map (rpc: { config = map (rpc: {
inherit (rpc) method; inherit (rpc) method;
} // (if rpc.params != { } then { inherit (rpc) params; } else { })) c; } // (optionalAttrs (rpc.params != { }) { inherit (rpc) params; })) c;
}) cfg.config.subsystems; }) cfg.config.subsystems;
}; };
configJSON = pkgs.writeText "spdk-config.json" (toJSON config'); configJSON = pkgs.writeText "spdk-config.json" (toJSON config');