nix: use directly nixUnstable
[sourcephile-nix.git] / nixos / modules / services / networking / netns.nix
index a4a238bc6bdf23f33273143461895ad875197178..95a6ee4a4461d2671635a8d36a139178d4bce215 100644 (file)
@@ -1,33 +1,33 @@
-{ pkgs, lib, config, ... }:
+{ pkgs, lib, config, options, ... }:
 with lib;
 let
   cfg = config.services.netns;
+  inherit (config) networking;
   # Escape as required by: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
   escapeUnitName = name:
     lib.concatMapStrings (s: if lib.isList s then "-" else s)
     (builtins.split "[^a-zA-Z0-9_.\\-]+" name);
+  systemd = import (pkgs.path + "/nixos/modules/system/boot/systemd-unit-options.nix") { inherit config lib; };
 in
 {
 options.services.netns = {
   namespaces = mkOption {
     description = "netns namespaces to create";
-    type = types.attrsOf (types.submodule ({ name, ... }: {
+    type = types.attrsOf (types.submodule {
       options = {
         nftables = mkOption {
           type = types.lines;
-          default = "";
+          default = networking.nftables.ruleset;
           description = ''
             Nftables ruleset.
           '';
         };
-        sysctl = mkOption {
-          type = with types; attrsOf (nullOr (oneOf [bool str int]));
-          default = {};
-          description = ''
-            Kernel sysctl.
-          '';
+        sysctl = options.boot.kernel.sysctl // {
+          default = config.boot.kernel.sysctl;
         };
         service = mkOption {
+          # Avoid error: The option `services.netns.namespaces.${netns}.service.startLimitIntervalSec' is used but not defined.
+          #type = types.submodule [ { options = builtins.removeAttrs systemd.serviceOptions ["startLimitIntervalSec"]; } ];
           type = types.attrs;
           default = {};
           description = ''
@@ -35,32 +35,42 @@ options.services.netns = {
           '';
         };
       };
-    }));
+    });
     default = {};
   };
 };
 config = {
   systemd.services = mapAttrs' (name: c:
     nameValuePair "netns-${escapeUnitName name}" (mkMerge [
-      { description = "${name} network namespace";
+      { description = mkForce "${name} network namespace";
         before = [ "network.target" ];
         serviceConfig = {
-          Type = "oneshot";
+          Type = mkForce "oneshot";
           RemainAfterExit = true;
           PrivateNetwork = true;
-          ExecStart = "${pkgs.iproute}/bin/ip netns add ${escapeShellArg name}";
-          ExecStartPost = optional config.networking.nftables.enable
-            "${pkgs.iproute}/bin/ip netns exec ${escapeShellArg name} ${pkgs.writeScript "nftables-ruleset" ''
-              #!${pkgs.nftables}/bin/nft -f
-              flush ruleset
-              ${c.nftables}
-            ''}";
-          ExecStop = "${pkgs.iproute}/bin/ip netns del ${escapeShellArg name}";
+          ExecStart = mkForce (pkgs.writeShellScript "netns-start" ''
+            test -e /var/run/netns/${escapeShellArg name} ||
+            ${pkgs.iproute}/bin/ip netns add ${escapeShellArg name}
+          '');
+          ExecStartPost =
+            # Use --ignore because some keys may no longer exist in that new namespace,
+            # like net.ipv6.conf.eth0.addr_gen_mode or net.core.rmem_max
+            [''${pkgs.iproute}/bin/ip netns exec ${escapeShellArg name} ${pkgs.procps}/bin/sysctl --ignore -p ${pkgs.writeScript "sysctl"
+                (concatStrings (mapAttrsToList (n: v: optionalString (v != null) "${n}=${if v == false then "0" else toString v}\n") c.sysctl))}
+            ''] ++
+            optional networking.nftables.enable ''
+              ${pkgs.iproute}/bin/ip netns exec ${escapeShellArg name} ${pkgs.writeScript "nftables-ruleset" ''
+                #!${pkgs.nftables}/bin/nft -f
+                flush ruleset
+                ${c.nftables}
+              ''}
+            '';
+          ExecStop = mkForce "${pkgs.iproute}/bin/ip netns del ${escapeShellArg name}";
         };
       }
-      #cfg.service
       c.service
-    ])) cfg.namespaces;
+    ]
+    )) cfg.namespaces;
   meta.maintainers = with lib.maintainers; [ julm ];
 };
 }