1{ networkd }:
2{ config, pkgs, ... }:
3let
4 inherit (pkgs) lib;
5 qemu-common = import ../../lib/qemu-common.nix { inherit lib pkgs; };
6 vlanIfs = lib.range 1 (lib.length config.virtualisation.vlans);
7in
8{
9 environment.systemPackages = [ pkgs.iptables ]; # to debug firewall rules
10 virtualisation.vlans = [
11 1
12 2
13 3
14 ];
15 boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true;
16 networking = {
17 useDHCP = false;
18 useNetworkd = networkd;
19 firewall.checkReversePath = true;
20 firewall.allowedUDPPorts = [ 547 ];
21 interfaces = lib.mkOverride 0 (
22 lib.listToAttrs (
23 lib.forEach vlanIfs (
24 n:
25 lib.nameValuePair "eth${toString n}" {
26 ipv4.addresses = [
27 {
28 address = "192.168.${toString n}.1";
29 prefixLength = 24;
30 }
31 ];
32 ipv6.addresses = [
33 {
34 address = "fd00:1234:5678:${toString n}::1";
35 prefixLength = 64;
36 }
37 ];
38 }
39 )
40 )
41 );
42 };
43 services.kea = {
44 dhcp4 = {
45 enable = true;
46 settings = {
47 interfaces-config = {
48 interfaces = map (n: "eth${toString n}") vlanIfs;
49 dhcp-socket-type = "raw";
50 service-sockets-require-all = true;
51 service-sockets-max-retries = 5;
52 service-sockets-retry-wait-time = 2500;
53 };
54 subnet4 = map (n: {
55 id = n;
56 subnet = "192.168.${toString n}.0/24";
57 pools = [ { pool = "192.168.${toString n}.3 - 192.168.${toString n}.254"; } ];
58 option-data = [
59 {
60 data = "192.168.${toString n}.1";
61 name = "routers";
62 }
63 {
64 data = "192.168.${toString n}.1";
65 name = "domain-name-servers";
66 }
67 ];
68
69 reservations = [
70 {
71 hw-address = qemu-common.qemuNicMac n 1;
72 hostname = "client${toString n}";
73 ip-address = "192.168.${toString n}.2";
74 }
75 ];
76 }) vlanIfs;
77 };
78 };
79 dhcp6 = {
80 enable = true;
81 settings = {
82 interfaces-config = {
83 interfaces = map (n: "eth${toString n}") vlanIfs;
84 service-sockets-require-all = true;
85 service-sockets-max-retries = 5;
86 service-sockets-retry-wait-time = 2500;
87 };
88
89 subnet6 = map (n: {
90 id = n;
91 subnet = "fd00:1234:5678:${toString n}::/64";
92 interface = "eth${toString n}";
93 pools = [ { pool = "fd00:1234:5678:${toString n}::2-fd00:1234:5678:${toString n}::2"; } ];
94 }) vlanIfs;
95 };
96 };
97 };
98 services.radvd = {
99 enable = true;
100 config = lib.flip lib.concatMapStrings vlanIfs (n: ''
101 interface eth${toString n} {
102 AdvSendAdvert on;
103 AdvManagedFlag on;
104 AdvOtherConfigFlag on;
105 RDNSS 2001:db8::1 {};
106
107 prefix fd00:1234:5678:${toString n}::/64 {
108 AdvAutonomous off;
109 };
110 };
111 '');
112 };
113}