mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-02-20 19:16:11 +00:00
Merge pull request #55122 from elseym/ndppd-module
ndppd module: refactor and fix
This commit is contained in:
commit
5a3a543078
@ -476,6 +476,14 @@
|
||||
</para>
|
||||
</note>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <link xlink:href="https://github.com/DanielAdolfsson/ndppd"><literal>ndppd</literal></link> module
|
||||
now supports <link linkend="opt-services.ndppd.enable">all config options</link> provided by the current
|
||||
upstream version as service options. Additionally the <literal>ndppd</literal> package doesn't contain
|
||||
the systemd unit configuration from upstream anymore, the unit is completely configured by the NixOS module now.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
</section>
|
||||
|
@ -5,43 +5,163 @@ 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.";
|
||||
};
|
||||
network = mkOption {
|
||||
type = types.string;
|
||||
default = "1111::";
|
||||
example = "2001:DB8::/32";
|
||||
description = "Network that we proxy.";
|
||||
};
|
||||
configFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
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;
|
||||
description = "Path to configuration file.";
|
||||
};
|
||||
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.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";
|
||||
};
|
||||
interface = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
description = "Interface to use when method is iface.";
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
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" ];
|
||||
description = "NDP Proxy Daemon";
|
||||
documentation = [ "man:ndppd(1)" "man:ndppd.conf(5)" ];
|
||||
after = [ "network-pre.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig.ExecStart = "${pkgs.ndppd}/bin/ndppd -c ${ndppdConf}";
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ gnidorah ];
|
||||
}
|
||||
|
@ -142,6 +142,7 @@ in
|
||||
nat.firewall = handleTest ./nat.nix { withFirewall = true; };
|
||||
nat.firewall-conntrack = handleTest ./nat.nix { withFirewall = true; withConntrackHelpers = true; };
|
||||
nat.standalone = handleTest ./nat.nix { withFirewall = false; };
|
||||
ndppd = handleTest ./ndppd.nix {};
|
||||
neo4j = handleTest ./neo4j.nix {};
|
||||
netdata = handleTest ./netdata.nix {};
|
||||
networking.networkd = handleTest ./networking.nix { networkd = true; };
|
||||
|
61
nixos/tests/ndppd.nix
Normal file
61
nixos/tests/ndppd.nix
Normal file
@ -0,0 +1,61 @@
|
||||
import ./make-test.nix ({ pkgs, lib, ...} : {
|
||||
name = "ndppd";
|
||||
meta = with pkgs.stdenv.lib.maintainers; {
|
||||
maintainers = [ fpletz ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
upstream = { pkgs, ... }: {
|
||||
environment.systemPackages = [ pkgs.tcpdump ];
|
||||
networking.useDHCP = false;
|
||||
networking.interfaces = {
|
||||
eth1 = {
|
||||
ipv6.addresses = [
|
||||
{ address = "fd23::1"; prefixLength = 112; }
|
||||
];
|
||||
ipv6.routes = [
|
||||
{ address = "fd42::";
|
||||
prefixLength = 112;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
server = { pkgs, ... }: {
|
||||
boot.kernel.sysctl = {
|
||||
"net.ipv6.conf.all.forwarding" = "1";
|
||||
"net.ipv6.conf.default.forwarding" = "1";
|
||||
};
|
||||
environment.systemPackages = [ pkgs.tcpdump ];
|
||||
networking.useDHCP = false;
|
||||
networking.interfaces = {
|
||||
eth1 = {
|
||||
ipv6.addresses = [
|
||||
{ address = "fd23::2"; prefixLength = 112; }
|
||||
];
|
||||
};
|
||||
};
|
||||
services.ndppd = {
|
||||
enable = true;
|
||||
interface = "eth1";
|
||||
network = "fd42::/112";
|
||||
};
|
||||
containers.client = {
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.255.1";
|
||||
localAddress = "192.168.255.2";
|
||||
hostAddress6 = "fd42::1";
|
||||
localAddress6 = "fd42::2";
|
||||
config = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
startAll;
|
||||
$server->waitForUnit("multi-user.target");
|
||||
$upstream->waitForUnit("multi-user.target");
|
||||
$upstream->waitUntilSucceeds("ping -c5 fd42::2");
|
||||
'';
|
||||
})
|
@ -1,11 +1,6 @@
|
||||
{ stdenv, fetchFromGitHub, fetchurl, gzip, ... }:
|
||||
{ stdenv, fetchFromGitHub, fetchurl, gzip }:
|
||||
|
||||
let
|
||||
serviceFile = fetchurl {
|
||||
url = "https://raw.githubusercontent.com/DanielAdolfsson/ndppd/f37e8eb33dc68b3385ecba9b36a5efd92755580f/ndppd.service";
|
||||
sha256 = "1zf54pzjfj9j9gr48075njqrgad4myd3dqmhvzxmjy4gjy9ixmyh";
|
||||
};
|
||||
in stdenv.mkDerivation rec {
|
||||
stdenv.mkDerivation rec {
|
||||
name = "ndppd-${version}";
|
||||
version = "0.2.5";
|
||||
|
||||
@ -27,11 +22,6 @@ in stdenv.mkDerivation rec {
|
||||
postInstall = ''
|
||||
mkdir -p $out/etc
|
||||
cp ndppd.conf-dist $out/etc/ndppd.conf
|
||||
|
||||
mkdir -p $out/lib/systemd/system
|
||||
# service file needed for our module is not in release yet
|
||||
substitute ${serviceFile} $out/lib/systemd/system/ndppd.service \
|
||||
--replace /usr/sbin/ndppd $out/sbin/ndppd
|
||||
'';
|
||||
|
||||
meta = {
|
||||
|
Loading…
Reference in New Issue
Block a user