10 cfg = config.services.frr;
33 daemonDefaultOptions = {
34 zebra = "-A 127.0.0.1 -s 90000000";
35 mgmtd = "-A 127.0.0.1";
36 bgpd = "-A 127.0.0.1";
37 ospfd = "-A 127.0.0.1";
39 ripd = "-A 127.0.0.1";
41 isisd = "-A 127.0.0.1";
42 pimd = "-A 127.0.0.1";
44 ldpd = "-A 127.0.0.1";
45 nhrpd = "-A 127.0.0.1";
46 eigrpd = "-A 127.0.0.1";
47 babeld = "-A 127.0.0.1";
48 sharpd = "-A 127.0.0.1";
49 pbrd = "-A 127.0.0.1";
50 staticd = "-A 127.0.0.1";
51 bfdd = "-A 127.0.0.1";
52 fabricd = "-A 127.0.0.1";
53 vrrpd = "-A 127.0.0.1";
54 pathd = "-A 127.0.0.1";
75 obsoleteServices = renamedServices ++ [
81 allDaemons = builtins.attrNames daemonDefaultOptions;
83 isEnabled = service: cfg.${service}.enable;
85 daemonLine = d: "${d}=${if isEnabled d then "yes" else "no"}";
88 if cfg.configFile != null then
91 pkgs.writeText "frr.conf" ''
94 hostname ${config.networking.hostName}
96 service password-encryption
97 service integrated-vtysh-config
107 options = lib.mkOption {
108 type = lib.types.listOf lib.types.str;
109 default = [ daemonDefaultOptions.${service} ];
111 Options for the FRR ${service} daemon.
114 extraOptions = lib.mkOption {
115 type = lib.types.listOf lib.types.str;
118 Extra options to be appended to the FRR ${service} daemon options.
123 if (builtins.elem service daemons) then { enable = lib.mkEnableOption "FRR ${service}"; } else { }
134 options.services.frr = {
135 configFile = lib.mkOption {
136 type = lib.types.nullOr lib.types.path;
138 example = "/etc/frr/frr.conf";
140 Configuration file to use for FRR.
141 By default the NixOS generated files are used.
144 config = lib.mkOption {
145 type = lib.types.lines;
151 network 10.0.0.0/8 area 0
153 neighbor 10.0.0.1 remote-as 65001
156 FRR configuration statements.
159 openFilesLimit = lib.mkOption {
160 type = lib.types.ints.unsigned;
163 This is the maximum number of FD's that will be available. Use a
164 reasonable value for your setup if you are expecting a large number
170 { options.services.frr = (lib.genAttrs allDaemons serviceOptions); }
171 (lib.mkRemovedOptionModule [ "services" "frr" "zebra" "enable" ] "FRR zebra is always enabled")
174 d: lib.mkRenamedOptionModule [ "services" "frr" d "enable" ] [ "services" "frr" "${d}d" "enable" ]
179 lib.mkRenamedOptionModule
180 [ "services" "frr" d "extraOptions" ]
181 [ "services" "frr" "${d}d" "extraOptions" ]
191 ++ (map (d: lib.mkRemovedOptionModule [ "services" "frr" d "enable" ] "FRR ${d}d is always enabled")
199 lib.mkRemovedOptionModule [
204 ] "FRR switched to integrated-vtysh-config, please use services.frr.config"
208 lib.mkRemovedOptionModule [ "services" "frr" d "configFile" ]
209 "FRR switched to integrated-vtysh-config, please use services.frr.config or services.frr.configFile"
213 lib.mkRemovedOptionModule [
218 ] "Please change -A option in services.frr.${d}.options instead"
222 lib.mkRemovedOptionModule [ "services" "frr" d "vtyListenPort" ]
223 "Please use `-P «vtyListenPort»` option with services.frr.${d}.extraOptions instead, or change services.frr.${d}.options accordingly"
226 ###### implementation
230 daemonList = lib.concatStringsSep "\n" (map daemonLine daemons);
232 d: "${d}_options=\"${lib.concatStringsSep " " (cfg.${d}.options ++ cfg.${d}.extraOptions)}\"";
233 daemonOptions = lib.concatStringsSep "\n" (map daemonOptionLine allDaemons);
235 lib.mkIf (lib.any isEnabled daemons || cfg.configFile != null || cfg.config != "") {
237 environment.systemPackages = [
238 pkgs.frr # for the vtysh tool
242 description = "FRR daemon user";
249 # Members of the frrvty group can use vtysh to inspect the FRR daemons
256 "frr/frr.conf".source = configFile;
257 "frr/vtysh.conf".text = ''
258 service integrated-vtysh-config
260 "frr/daemons".text = ''
261 # This file tells the frr package which daemons to start.
263 # The watchfrr, zebra and staticd daemons are always started.
265 # This part is auto-generated from services.frr.<daemon>.enable config
268 # If this option is set the /etc/init.d/frr script automatically loads
269 # the config via "vtysh -b" when the servers are started.
273 # This part is auto-generated from services.frr.<daemon>.options or
274 # services.frr.<daemon>.extraOptions
279 systemd.tmpfiles.rules = [ "d /run/frr 0755 frr frr -" ];
281 systemd.services.frr = {
282 description = "FRRouting";
283 documentation = [ "https://frrouting.readthedocs.io/en/latest/setup.html" ];
284 wants = [ "network.target" ];
287 "systemd-sysctl.service"
289 before = [ "network.target" ];
290 wantedBy = [ "multi-user.target" ];
291 startLimitIntervalSec = 180;
292 reloadIfChanged = true;
300 NotifyAccess = "all";
301 StartLimitBurst = "3";
306 LimitNOFILE = cfg.openFilesLimit;
307 PIDFile = "/run/frr/watchfrr.pid";
308 ExecStart = "${pkgs.frr}/libexec/frr/frrinit.sh start";
309 ExecStop = "${pkgs.frr}/libexec/frr/frrinit.sh stop";
310 ExecReload = "${pkgs.frr}/libexec/frr/frrinit.sh reload";
315 meta.maintainers = with lib.maintainers; [ woffs ];