summaryrefslogtreecommitdiffstats
path: root/nixos/modules/services/networking/ndppd.nix
diff options
context:
space:
mode:
authorelseym <elseym@me.com>2019-02-02 15:37:48 +0100
committerelseym <elseym@me.com>2019-02-03 14:28:54 +0100
commit4ce1c5938905eedd1050f0be8a0c6a69587f5aac (patch)
tree6f92250059fb7079d0e42ec7757df8e8f4d51f95 /nixos/modules/services/networking/ndppd.nix
parentf1b91b5726c901ccb7056836d0882c7532883b36 (diff)
ndppd module: refactor
Diffstat (limited to 'nixos/modules/services/networking/ndppd.nix')
-rw-r--r--nixos/modules/services/networking/ndppd.nix168
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.&lt;interface&gt;.rules.&lt;network&gt; instead)
+ '';
+ default = null;
+ example = "eth0";
+ };
+ network = mkOption {
+ type = types.nullOr types.str;
+ description = ''
+ Network that we proxy.
+ (Legacy option, use services.ndppd.proxies.&lt;interface&gt;.rules.&lt;network&gt; 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 ];
}