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