summary refs log tree commit diff
path: root/modules
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2025-09-01 23:11:30 +0200
committerMel <mel@rnrd.eu>2025-09-01 23:11:30 +0200
commite24e1c28c5baf531dcf64c1f1b737c10f1fe8ef4 (patch)
treee769f8e94dddf55b977cbada62fb64b37df7c608 /modules
parent4b56528d17d44e8340b9ccdc80ef01532ff8bd8b (diff)
downloadnetwork-e24e1c28c5baf531dcf64c1f1b737c10f1fe8ef4.tar.zst
network-e24e1c28c5baf531dcf64c1f1b737c10f1fe8ef4.zip
Allow disabling IPv6 for foundation service networks
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'modules')
-rw-r--r--modules/foundation/services/default.nix7
-rw-r--r--modules/foundation/services/networks.nix127
2 files changed, 82 insertions, 52 deletions
diff --git a/modules/foundation/services/default.nix b/modules/foundation/services/default.nix
index f26f9e6..8136ce0 100644
--- a/modules/foundation/services/default.nix
+++ b/modules/foundation/services/default.nix
@@ -10,8 +10,11 @@
     enable = true;
     default = true;
 
-    subnet = "2001:d0c:1::/48";
-    gateway = "2001:d0c:1::1";
     driver = "bridge";
+    ipv6 = {
+      enable = true;
+      subnet = "2001:d0c:1::/48";
+      gateway = "2001:d0c:1::1";
+    };
   };
 }
diff --git a/modules/foundation/services/networks.nix b/modules/foundation/services/networks.nix
index 8be5723..ed2bf9e 100644
--- a/modules/foundation/services/networks.nix
+++ b/modules/foundation/services/networks.nix
@@ -26,6 +26,17 @@ let
   inherit (utils) naming;
 
   cfg = config.foundation;
+
+  # this could be moved out into library functions, it's pretty useful.
+  # mapAttrsIndexed' :: (Int -> String -> AttrSet -> { name:: String; value :: Any; }) -> AttrSet -> AttrSet
+  mapAttrsIndexed' = f: attrs: listToAttrs (imap0 (i: v: f i v.name v.value) (attrsToList attrs));
+  # mapAttrsIndexed :: (Int -> String -> AttrSet -> Any) -> AttrSet -> AttrSet
+  mapAttrsIndexed =
+    f: attrs:
+    mapAttrsIndexed' (
+      i: n: v:
+      nameValuePair v.name (f i v.name v.value)
+    ) attrs;
 in
 {
   options.foundation =
@@ -49,25 +60,43 @@ in
               '';
             };
 
-            subnet = mkOption {
-              type = types.nullOr types.str;
-              description = ''
-                IPv6 subnet for this network in CIDR notation.
-                Don't set to get a random subnet assigned to you within
-                the subnet defined in `defaultSubnetPrefix`.
-              '';
-              example = "2001:d0c:123::/64";
-              default = null;
-            };
+            # we rely on docker to give us our
+            # ipv4 settings automatically, but
+            # maybe we want another module like
+            # this for ipv4?
+            ipv6 = mkOption {
+              type = types.submodule {
+                options = {
+                  enable = mkOption {
+                    type = types.bool;
+                    default = true;
+                    description = "Should this network have IPv6?";
+                  };
 
-            gateway = mkOption {
-              type = types.nullOr types.str;
-              description = ''
-                IPv6 gateway for this network.
-                Should match the subnet.
-              '';
-              example = "2001:d0c:123::1";
-              default = null;
+                  subnet = mkOption {
+                    type = types.nullOr types.str;
+                    description = ''
+                      IPv6 subnet for this network in CIDR notation.
+                      Don't set to get a random subnet assigned to you within
+                      the subnet defined in `defaultIPv6SubnetPrefix`.
+                    '';
+                    example = "2001:d0c:123::/64";
+                    default = null;
+                  };
+
+                  gateway = mkOption {
+                    type = types.nullOr types.str;
+                    description = ''
+                      IPv6 gateway for this network.
+                      Should match the subnet.
+                    '';
+                    example = "2001:d0c:123::1";
+                    default = null;
+                  };
+                };
+              };
+              description = "IPv6 settings for network";
+              default = { };
             };
 
             driver = mkOption {
@@ -120,22 +149,22 @@ in
         '';
       };
 
-      defaultSubnetPrefix = mkOption {
+      defaultIPv6SubnetPrefix = mkOption {
         type = types.str;
         description = ''
           Default network subnet assigned to networks without
           a set subnet.
-          Prefix length defined by `defaultSubnetLength`.
+          Prefix length defined by `defaultIPv6SubnetLength`.
         '';
         default = "2001:d0c";
       };
 
-      defaultSubnetLength = mkOption {
+      defaultIPv6SubnetLength = mkOption {
         type = types.int;
         description = ''
           Default network subnet length assigned to networks without
           a set subnet.
-          This should always be the length of the `defaultSubnetPrefix` + 16.
+          This should always be the length of the `defaultIPv6SubnetPrefix` + 16.
         '';
         default = 48;
       };
@@ -160,7 +189,7 @@ in
       experimental = true;
       ipv6 = true;
       ip6tables = true;
-      fixed-cidr-v6 = "${cfg.defaultSubnetPrefix}:255::/${toString cfg.defaultSubnetLength}";
+      fixed-cidr-v6 = "${cfg.defaultIPv6SubnetPrefix}:255::/${toString cfg.defaultIPv6SubnetLength}";
     };
 
     boot.kernel.sysctl = {
@@ -192,28 +221,32 @@ in
     systemd.services =
       let
         prefixOffset = 100;
-        prefixByIndex = i: "${cfg.defaultSubnetPrefix}:${toString (prefixOffset + i)}";
-        subnetByIndex = i: "${prefixByIndex i}::/${toString cfg.defaultSubnetLength}";
+        prefixByIndex = i: "${cfg.defaultIPv6SubnetPrefix}:${toString (prefixOffset + i)}";
+        subnetByIndex = i: "${prefixByIndex i}::/${toString cfg.defaultIPv6SubnetLength}";
         gatewayByIndex = i: "${prefixByIndex i}::1";
 
-        # this could be moved out into library functions, it's pretty useful.
-        # mapAttrsIndexed' :: (Int -> String -> AttrSet -> { name:: String; value :: Any; }) -> AttrSet -> AttrSet
-        mapAttrsIndexed' = f: attrs: listToAttrs (imap0 (i: v: f i v.name v.value) (attrsToList attrs));
-        # mapAttrsIndexed :: (Int -> String -> AttrSet -> Any) -> AttrSet -> AttrSet
-        mapAttrsIndexed =
-          f: attrs:
-          mapAttrsIndexed' (
-            i: n: v:
-            nameValuePair v.name (f i v.name v.value)
-          ) attrs;
-
         networkService =
           index: name: network:
           let
+            inherit (network)
+              ipv6
+              driver
+              mtu
+              options
+              serviceGroup
+              ;
+
             docker = getExe pkgs.docker;
-            options = concatStringsSep " " network.options;
-            subnet = if network.subnet == null then subnetByIndex index else network.subnet;
-            gateway = if network.gateway == null then gatewayByIndex index else network.gateway;
+
+            subnet = if ipv6.subnet == null then subnetByIndex index else ipv6.subnet;
+            gateway = if ipv6.gateway == null then gatewayByIndex index else ipv6.gateway;
+
+            extraOptions = concatStringsSep " " options;
+            ipv6Options = concatStringsSep " " [
+              "--ipv6"
+              "--subnet=${subnet}"
+              "--gateway=${gateway}"
+            ];
           in
           {
             description = "Docker service network '${name}'";
@@ -221,9 +254,7 @@ in
             requires = [ "docker.service" ];
 
             wantedBy = [ "multi-user.target" ];
-            partOf = optional (
-              network.serviceGroup != null
-            ) "${naming.groupTarget network.serviceGroup}.target";
+            partOf = optional (network.serviceGroup != null) "${naming.groupTarget serviceGroup}.target";
 
             serviceConfig = {
               Type = "oneshot";
@@ -235,14 +266,10 @@ in
                 fi
 
                 ${docker} network create \
-                  --ipv6 \
-                  --subnet=${subnet} \
-                  --gateway=${gateway} \
-                  --driver=${network.driver} \
-                  ${
-                    optionalString (network.mtu != null) "--opt com.docker.network.driver.mtu=${toString network.mtu}"
-                  } \
-                  ${options} \
+                  --driver=${driver} \
+                  ${optionalString (ipv6.enable) ipv6Options} \
+                  ${optionalString (mtu != null) "--opt com.docker.network.driver.mtu=${toString network.mtu}"} \
+                  ${extraOptions} \
                   ${name}
               '';