diff options
author | elseym <elseym@me.com> | 2019-02-02 15:37:48 +0100 |
---|---|---|
committer | elseym <elseym@me.com> | 2019-02-03 14:28:54 +0100 |
commit | 4ce1c5938905eedd1050f0be8a0c6a69587f5aac (patch) | |
tree | 6f92250059fb7079d0e42ec7757df8e8f4d51f95 /nixos/modules/services/networking/ndppd.nix | |
parent | f1b91b5726c901ccb7056836d0882c7532883b36 (diff) |
ndppd module: refactor
Diffstat (limited to 'nixos/modules/services/networking/ndppd.nix')
-rw-r--r-- | nixos/modules/services/networking/ndppd.nix | 168 |
1 files changed, 143 insertions, 25 deletions
diff --git a/nixos/modules/services/networking/ndppd.nix b/nixos/modules/services/networking/ndppd.nix index 1d6c48dd8d37..54a6e393657f 100644 --- a/nixos/modules/services/networking/ndppd.nix +++ b/nixos/modules/services/networking/ndppd.nix @@ -5,43 +5,161 @@ with lib; let cfg = config.services.ndppd; - configFile = pkgs.runCommand "ndppd.conf" {} '' - substitute ${pkgs.ndppd}/etc/ndppd.conf $out \ - --replace eth0 ${cfg.interface} \ - --replace 1111:: ${cfg.network} - ''; -in { - options = { - services.ndppd = { - enable = mkEnableOption "daemon that proxies NDP (Neighbor Discovery Protocol) messages between interfaces"; + render = s: f: concatStringsSep "\n" (mapAttrsToList f s); + prefer = a: b: if a != null then a else b; + + ndppdConf = prefer cfg.configFile (pkgs.writeText "ndppd.conf" '' + route-ttl ${toString cfg.routeTTL} + ${render cfg.proxies (proxyInterfaceName: proxy: '' + proxy ${prefer proxy.interface proxyInterfaceName} { + router ${boolToString proxy.router} + timeout ${toString proxy.timeout} + ttl ${toString proxy.ttl} + ${render proxy.rules (ruleNetworkName: rule: '' + rule ${prefer rule.network ruleNetworkName} { + ${rule.method}${if rule.method == "iface" then " ${rule.interface}" else ""} + }'')} + }'')} + ''); + + proxy = types.submodule { + options = { interface = mkOption { - type = types.string; - default = "eth0"; - example = "ens3"; - description = "Interface which is on link-level with router."; + type = types.nullOr types.str; + description = '' + Listen for any Neighbor Solicitation messages on this interface, + and respond to them according to a set of rules. + Defaults to the name of the attrset. + ''; + default = null; + }; + router = mkOption { + type = types.bool; + description = '' + Turns on or off the router flag for Neighbor Advertisement Messages. + ''; + default = true; + }; + timeout = mkOption { + type = types.int; + description = '' + Controls how long to wait for a Neighbor Advertisment Message before + invalidating the entry, in milliseconds. + ''; + default = 500; + }; + ttl = mkOption { + type = types.int; + description = '' + Controls how long a valid or invalid entry remains in the cache, in + milliseconds. + ''; + default = 30000; }; + rules = mkOption { + type = types.attrsOf rule; + description = '' + This is a rule that the target address is to match against. If no netmask + is provided, /128 is assumed. You may have several rule sections, and the + addresses may or may not overlap. + ''; + default = {}; + }; + }; + }; + + rule = types.submodule { + options = { network = mkOption { - type = types.string; - default = "1111::"; - example = "2001:DB8::/32"; - description = "Network that we proxy."; + type = types.nullOr types.str; + description = '' + This is the target address is to match against. If no netmask + is provided, /128 is assumed. The addresses of serveral rules + may or may not overlap. + Defaults to the name of the attrset. + ''; + default = null; + }; + method = mkOption { + type = types.enum [ "static" "iface" "auto" ]; + description = '' + static: Immediately answer any Neighbor Solicitation Messages + (if they match the IP rule). + iface: Forward the Neighbor Solicitation Message through the specified + interface and only respond if a matching Neighbor Advertisement + Message is received. + auto: Same as iface, but instead of manually specifying the outgoing + interface, check for a matching route in /proc/net/ipv6_route. + ''; + default = "auto"; }; - configFile = mkOption { - type = types.nullOr types.path; + interface = mkOption { + type = types.nullOr types.str; + description = "Interface to use when method is iface."; default = null; - description = "Path to configuration file."; }; }; }; +in { + options.services.ndppd = { + enable = mkEnableOption "daemon that proxies NDP (Neighbor Discovery Protocol) messages between interfaces"; + interface = mkOption { + type = types.nullOr types.str; + description = '' + Interface which is on link-level with router. + (Legacy option, use services.ndppd.proxies.<interface>.rules.<network> instead) + ''; + default = null; + example = "eth0"; + }; + network = mkOption { + type = types.nullOr types.str; + description = '' + Network that we proxy. + (Legacy option, use services.ndppd.proxies.<interface>.rules.<network> instead) + ''; + default = null; + example = "1111::/64"; + }; + configFile = mkOption { + type = types.nullOr types.path; + description = "Path to configuration file."; + default = null; + }; + routeTTL = mkOption { + type = types.int; + description = '' + This tells 'ndppd' how often to reload the route file /proc/net/ipv6_route, + in milliseconds. + ''; + default = 30000; + }; + proxies = mkOption { + type = types.attrsOf proxy; + description = '' + This sets up a listener, that will listen for any Neighbor Solicitation + messages, and respond to them according to a set of rules. + ''; + default = {}; + example = { "eth0".rules."1111::/64" = {}; }; + }; + }; + config = mkIf cfg.enable { - systemd.packages = [ pkgs.ndppd ]; - environment.etc."ndppd.conf".source = if (cfg.configFile != null) then cfg.configFile else configFile; + warnings = mkIf (cfg.interface != null && cfg.network != null) [ '' + The options services.ndppd.interface and services.ndppd.network will probably be removed soon, + please use services.ndppd.proxies.<interface>.rules.<network> instead. + '' ]; + + services.ndppd.proxies = mkIf (cfg.interface != null && cfg.network != null) { + "${cfg.interface}".rules."${cfg.network}" = {}; + }; + systemd.services.ndppd = { - serviceConfig.RuntimeDirectory = [ "ndppd" ]; + after = [ "network-pre.target" ]; wantedBy = [ "multi-user.target" ]; + serviceConfig.ExecStart = "${pkgs.ndppd}/bin/ndppd -c ${ndppdConf}"; }; }; - - meta.maintainers = with maintainers; [ gnidorah ]; } |