{ config, lib, ... }: with lib; let cfg = config.clerie.gre-tunnel; checkOpts = { config, ... }@moduleAttrs: { options = { remote = mkOption { type = types.str; }; local = mkOption { type = types.str; }; address = mkOption { type = types.str; }; }; }; in { options = { clerie.gre-tunnel = { enable = mkEnableOption "Declarative Policy-Routing"; ipv6 = mkOption { type = with types; attrsOf (submodule checkOpts); }; ipv4 = mkOption { type = with types; attrsOf (submodule checkOpts); }; }; }; config = mkIf cfg.enable { clerie.gre-tunnel.rules = [ { rule = "lookup main"; prio = 32000; } ]; networking.localCommands = '' ${concatMapStringsSep "\n" ( mapAttrsToList ( name: tunnel: '' ip -6 tunnel add ${name} mode gre remote ${tunnel.remote} local ${tunnel.local} ip link set ${name} up ip -6 a add ${tunnel.address} dev ${name} '') cfg.ipv6 ) } ${concatMapStringsSep "\n" ( mapAttrsToList ( name: tunnel: '' ip -4 tunnel add ${name} mode gre remote ${tunnel.remote} local ${tunnel.local} ip link set ${name} up ip -4 a add ${tunnel.address} dev ${name} '') cfg.ipv4 ) } ''; }; }