1{ config, lib, pkgs, ... }:
2
3let
4 inherit (lib) mkEnableOption mkIf mkOption types;
5
6 generic = variant:
7 let
8 cfg = config.services.${variant};
9 pkg = pkgs.${variant};
10 birdBin = if variant == "bird6" then "bird6" else "bird";
11 birdc = if variant == "bird6" then "birdc6" else "birdc";
12 descr =
13 { bird = "1.9.x with IPv4 suport";
14 bird6 = "1.9.x with IPv6 suport";
15 bird2 = "2.x";
16 }.${variant};
17 configFile = pkgs.stdenv.mkDerivation {
18 name = "${variant}.conf";
19 text = cfg.config;
20 preferLocalBuild = true;
21 buildCommand = ''
22 echo -n "$text" > $out
23 ${pkg}/bin/${birdBin} -d -p -c $out
24 '';
25 };
26 in {
27 ###### interface
28 options = {
29 services.${variant} = {
30 enable = mkEnableOption "BIRD Internet Routing Daemon (${descr})";
31 config = mkOption {
32 type = types.lines;
33 description = ''
34 BIRD Internet Routing Daemon configuration file.
35 <link xlink:href='http://bird.network.cz/'/>
36 '';
37 };
38 };
39 };
40
41 ###### implementation
42 config = mkIf cfg.enable {
43 environment.systemPackages = [ pkg ];
44 systemd.services.${variant} = {
45 description = "BIRD Internet Routing Daemon (${descr})";
46 wantedBy = [ "multi-user.target" ];
47 reloadIfChanged = true;
48 serviceConfig = {
49 Type = "forking";
50 Restart = "on-failure";
51 ExecStart = "${pkg}/bin/${birdBin} -c ${configFile} -u ${variant} -g ${variant}";
52 ExecReload = "${pkg}/bin/${birdc} configure";
53 ExecStop = "${pkg}/bin/${birdc} down";
54 CapabilityBoundingSet = [ "CAP_CHOWN" "CAP_FOWNER" "CAP_DAC_OVERRIDE" "CAP_SETUID" "CAP_SETGID"
55 # see bird/sysdep/linux/syspriv.h
56 "CAP_NET_BIND_SERVICE" "CAP_NET_BROADCAST" "CAP_NET_ADMIN" "CAP_NET_RAW" ];
57 ProtectSystem = "full";
58 ProtectHome = "yes";
59 SystemCallFilter="~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io";
60 MemoryDenyWriteExecute = "yes";
61 };
62 };
63 users = {
64 users.${variant} = {
65 description = "BIRD Internet Routing Daemon user";
66 group = variant;
67 };
68 groups.${variant} = {};
69 };
70 };
71 };
72
73in
74
75{
76 imports = map generic [ "bird" "bird6" "bird2" ];
77}