Merge pull request #151946 from mweinelt/frr

frr: init at 8.1; libyang: init at 2.0.112
This commit is contained in:
0x4A6F 2022-01-12 20:51:12 +01:00 committed by GitHub
commit 1e0d877e1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 530 additions and 0 deletions

View File

@ -75,6 +75,14 @@
<link linkend="opt-services.filebeat.enable">services.filebeat</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://frrouting.org/">FRRouting</link>, a
popular suite of Internet routing protocol daemons (BGP, BFD,
OSPF, IS-IS, VVRP and others). Available as
<link linkend="opt-services.ffr.babel.enable">services.frr</link>
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://github.com/hifi/heisenbridge">heisenbridge</link>,

View File

@ -19,12 +19,15 @@ In addition to numerous new and upgraded packages, this release has the followin
## New Services {#sec-release-22.05-new-services}
- [aesmd](https://github.com/intel/linux-sgx#install-the-intelr-sgx-psw), the Intel SGX Architectural Enclave Service Manager. Available as [services.aesmd](#opt-services.aesmd.enable).
- [rootless Docker](https://docs.docker.com/engine/security/rootless/), a `systemd --user` Docker service which runs without root permissions. Available as [virtualisation.docker.rootless.enable](options.html#opt-virtualisation.docker.rootless.enable).
- [matrix-conduit](https://conduit.rs/), a simple, fast and reliable chat server powered by matrix. Available as [services.matrix-conduit](option.html#opt-services.matrix-conduit.enable).
- [filebeat](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-overview.html), a lightweight shipper for forwarding and centralizing log data. Available as [services.filebeat](#opt-services.filebeat.enable).
- [FRRouting](https://frrouting.org/), a popular suite of Internet routing protocol daemons (BGP, BFD, OSPF, IS-IS, VVRP and others). Available as [services.frr](#opt-services.ffr.babel.enable)
- [heisenbridge](https://github.com/hifi/heisenbridge), a bouncer-style Matrix IRC bridge. Available as [services.heisenbridge](options.html#opt-services.heisenbridge.enable).
- [PowerDNS-Admin](https://github.com/ngoduykhanh/PowerDNS-Admin), a web interface for the PowerDNS server. Available at [services.powerdns-admin](options.html#opt-services.powerdns-admin.enable).

View File

@ -747,6 +747,7 @@
./services/networking/flannel.nix
./services/networking/freenet.nix
./services/networking/freeradius.nix
./services/networking/frr.nix
./services/networking/gateone.nix
./services/networking/gdomap.nix
./services/networking/ghostunnel.nix

View File

@ -0,0 +1,211 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.frr;
services = [
"static"
"bgp"
"ospf"
"ospf6"
"rip"
"ripng"
"isis"
"pim"
"ldp"
"nhrp"
"eigrp"
"babel"
"sharp"
"pbr"
"bfd"
"fabric"
];
allServices = services ++ [ "zebra" ];
isEnabled = service: cfg.${service}.enable;
daemonName = service: if service == "zebra" then service else "${service}d";
configFile = service:
let
scfg = cfg.${service};
in
if scfg.configFile != null then scfg.configFile
else pkgs.writeText "${daemonName service}.conf"
''
! FRR ${daemonName service} configuration
!
hostname ${config.networking.hostName}
log syslog
service password-encryption
!
${scfg.config}
!
end
'';
serviceOptions = service:
{
enable = mkEnableOption "the FRR ${toUpper service} routing protocol";
configFile = mkOption {
type = types.nullOr types.path;
default = null;
example = "/etc/frr/${daemonName service}.conf";
description = ''
Configuration file to use for FRR ${daemonName service}.
By default the NixOS generated files are used.
'';
};
config = mkOption {
type = types.lines;
default = "";
example =
let
examples = {
rip = ''
router rip
network 10.0.0.0/8
'';
ospf = ''
router ospf
network 10.0.0.0/8 area 0
'';
bgp = ''
router bgp 65001
neighbor 10.0.0.1 remote-as 65001
'';
};
in
examples.${service} or "";
description = ''
${daemonName service} configuration statements.
'';
};
vtyListenAddress = mkOption {
type = types.str;
default = "localhost";
description = ''
Address to bind to for the VTY interface.
'';
};
vtyListenPort = mkOption {
type = types.nullOr types.int;
default = null;
description = ''
TCP Port to bind to for the VTY interface.
'';
};
};
in
{
###### interface
imports = [
{
options.services.frr = {
zebra = (serviceOptions "zebra") // {
enable = mkOption {
type = types.bool;
default = any isEnabled services;
description = ''
Whether to enable the Zebra routing manager.
The Zebra routing manager is automatically enabled
if any routing protocols are configured.
'';
};
};
};
}
{ options.services.frr = (genAttrs services serviceOptions); }
];
###### implementation
config = mkIf (any isEnabled allServices) {
environment.systemPackages = [
pkgs.frr # for the vtysh tool
];
users.users.frr = {
description = "FRR daemon user";
isSystemUser = true;
group = "frr";
};
users.groups = {
frr = {};
# Members of the frrvty group can use vtysh to inspect the FRR daemons
frrvty = { members = [ "frr" ]; };
};
environment.etc = let
mkEtcLink = service: {
name = "frr/${service}.conf";
value.source = configFile service;
};
in
(builtins.listToAttrs
(map mkEtcLink (filter isEnabled allServices))) // {
"frr/vtysh.conf".text = "";
};
systemd.tmpfiles.rules = [
"d /run/frr 0750 frr frr -"
];
systemd.services =
let
frrService = service:
let
scfg = cfg.${service};
daemon = daemonName service;
in
nameValuePair daemon ({
wantedBy = [ "multi-user.target" ];
after = [ "network-pre.target" "systemd-sysctl.service" ] ++ lib.optionals (service != "zebra") [ "zebra.service" ];
bindsTo = lib.optionals (service != "zebra") [ "zebra.service" ];
wants = [ "network.target" ];
description = if service == "zebra" then "FRR Zebra routing manager"
else "FRR ${toUpper service} routing daemon";
unitConfig.Documentation = if service == "zebra" then "man:zebra(8)"
else "man:${daemon}(8) man:zebra(8)";
restartTriggers = [
(configFile service)
];
reloadIfChanged = true;
serviceConfig = {
PIDFile = "frr/${daemon}.pid";
ExecStart = "${pkgs.frr}/libexec/frr/${daemon} -f /etc/frr/${service}.conf"
+ optionalString (scfg.vtyListenAddress != "") " -A ${scfg.vtyListenAddress}"
+ optionalString (scfg.vtyListenPort != null) " -P ${toString scfg.vtyListenPort}";
ExecReload = "${pkgs.python3.interpreter} ${pkgs.frr}/libexec/frr/frr-reload.py --reload --daemon ${daemonName service} --bindir ${pkgs.frr}/bin --rundir /run/frr /etc/frr/${service}.conf";
Restart = "on-abnormal";
};
});
in
listToAttrs (map frrService (filter isEnabled allServices));
};
meta.maintainers = with lib.maintainers; [ woffs ];
}

View File

@ -143,6 +143,7 @@ in
fluidd = handleTest ./fluidd.nix {};
fontconfig-default-fonts = handleTest ./fontconfig-default-fonts.nix {};
freeswitch = handleTest ./freeswitch.nix {};
frr = handleTest ./frr.nix {};
fsck = handleTest ./fsck.nix {};
ft2-clone = handleTest ./ft2-clone.nix {};
gerrit = handleTest ./gerrit.nix {};

104
nixos/tests/frr.nix Normal file
View File

@ -0,0 +1,104 @@
# This test runs FRR and checks if OSPF routing works.
#
# Network topology:
# [ client ]--net1--[ router1 ]--net2--[ router2 ]--net3--[ server ]
#
# All interfaces are in OSPF Area 0.
import ./make-test-python.nix ({ pkgs, ... }:
let
ifAddr = node: iface: (pkgs.lib.head node.config.networking.interfaces.${iface}.ipv4.addresses).address;
ospfConf1 = ''
router ospf
network 192.168.0.0/16 area 0
'';
ospfConf2 = ''
interface eth2
ip ospf hello-interval 1
ip ospf dead-interval 5
!
router ospf
network 192.168.0.0/16 area 0
'';
in
{
name = "frr";
meta = with pkgs.lib.maintainers; {
maintainers = [ hexa ];
};
nodes = {
client =
{ nodes, ... }:
{
virtualisation.vlans = [ 1 ];
networking.defaultGateway = ifAddr nodes.router1 "eth1";
};
router1 =
{ ... }:
{
virtualisation.vlans = [ 1 2 ];
boot.kernel.sysctl."net.ipv4.ip_forward" = "1";
networking.firewall.extraCommands = "iptables -A nixos-fw -i eth2 -p ospfigp -j ACCEPT";
services.frr.ospf = {
enable = true;
config = ospfConf1;
};
specialisation.ospf.configuration = {
services.frr.ospf.config = ospfConf2;
};
};
router2 =
{ ... }:
{
virtualisation.vlans = [ 3 2 ];
boot.kernel.sysctl."net.ipv4.ip_forward" = "1";
networking.firewall.extraCommands = "iptables -A nixos-fw -i eth2 -p ospfigp -j ACCEPT";
services.frr.ospf = {
enable = true;
config = ospfConf2;
};
};
server =
{ nodes, ... }:
{
virtualisation.vlans = [ 3 ];
networking.defaultGateway = ifAddr nodes.router2 "eth1";
};
};
testScript =
{ nodes, ... }:
''
start_all()
# Wait for the networking to start on all machines
for machine in client, router1, router2, server:
machine.wait_for_unit("network.target")
with subtest("Wait for Zebra and OSPFD"):
for gw in router1, router2:
gw.wait_for_unit("zebra")
gw.wait_for_unit("ospfd")
router1.succeed("${nodes.router1.config.system.build.toplevel}/specialisation/ospf/bin/switch-to-configuration test >&2")
with subtest("Wait for OSPF to form adjacencies"):
for gw in router1, router2:
gw.wait_until_succeeds("vtysh -c 'show ip ospf neighbor' | grep Full")
gw.wait_until_succeeds("vtysh -c 'show ip route' | grep '^O>'")
with subtest("Test ICMP"):
client.wait_until_succeeds("ping -c 3 server >&2")
'';
})

View File

@ -0,0 +1,61 @@
{ stdenv
, lib
, fetchFromGitHub
# build time
, cmake
, pkg-config
# run time
, pcre2
# update script
, genericUpdater
, common-updater-scripts
}:
stdenv.mkDerivation rec {
pname = "libyang";
version = "2.0.112";
src = fetchFromGitHub {
owner = "CESNET";
repo = "libyang";
rev = "v${version}";
sha256 = "sha256-f8x0tC3XcQ9fnUE987GYw8qEo/B+J759vpCImqG3QWs=";
};
nativeBuildInputs = [
cmake
pkg-config
];
buildInputs = [
pcre2
];
cmakeFlags = [
"-DCMAKE_INSTALL_LIBDIR=lib"
"-DCMAKE_INSTALL_INCLUDEDIR=include"
"-DCMAKE_BUILD_TYPE:String=Release"
];
passthru.updateScript = genericUpdater {
inherit pname version;
versionLister = "${common-updater-scripts}/bin/list-git-tags ${src.meta.homepage}";
rev-prefix = "v";
};
meta = with lib; {
description = "YANG data modelling language parser and toolkit";
longDescription = ''
libyang is a YANG data modelling language parser and toolkit written (and
providing API) in C. The library is used e.g. in libnetconf2, Netopeer2,
sysrepo or FRRouting projects.
'';
homepage = "https://github.com/CESNET/libyang";
license = with licenses; [ bsd3 ];
platforms = platforms.unix;
maintainers = with maintainers; [ woffs ];
};
}

View File

@ -0,0 +1,137 @@
{ lib
, stdenv
, fetchFromGitHub
, fetchpatch
, python3Packages
# build time
, autoreconfHook
, flex
, bison
, perl
, pkg-config
, texinfo
# runtime
, c-ares
, json_c
, libcap
, libelf
, libunwind
, libyang
, net-snmp
, openssl
, pam
, pcre2
, python3
, readline
# tests
, nettools
, nixosTests
}:
stdenv.mkDerivation rec {
pname = "frr";
version = "8.1";
src = fetchFromGitHub {
owner = "FRRouting";
repo = pname;
rev = "${pname}-${version}";
sha256 = "sha256-hJcgLiPBxOE5QEh0RhtZhM3dOxFqW5H0TUjN+aP4qRk=";
};
patches = [
(fetchpatch {
# Fix clippy build on aarch64-linux
# https://github.com/FRRouting/frr/issues/10267
url = "https://github.com/FRRouting/frr/commit/3942ee1f7bc754dd0dd9ae79f89d0f2635be334f.patch";
sha256 = "1i0acfy5k9fbm9cxchrcvkhyw9704srq4wm2hyjqgdimm2dq7ryf";
})
];
nativeBuildInputs = [
autoreconfHook
bison
flex
perl
pkg-config
python3Packages.sphinx
texinfo
];
buildInputs = [
c-ares
json_c
libelf
libunwind
libyang
net-snmp
openssl
pam
pcre2
python3
readline
] ++ lib.optionals stdenv.isLinux [
libcap
];
configureFlags = [
"--sysconfdir=/etc/frr"
"--localstatedir=/run/frr"
"--sbindir=$(out)/libexec/frr"
"--disable-exampledir"
"--enable-user=frr"
"--enable-group=frr"
"--enable-configfile-mask=0640"
"--enable-logfile-mask=0640"
"--enable-vty-group=frrvty"
"--enable-snmp"
"--enable-multipath=64"
];
postPatch = ''
substituteInPlace tools/frr-reload --replace /usr/lib/frr/ $out/libexec/frr/
'';
doCheck = true;
checkInputs = [
nettools
python3Packages.pytest
];
enableParallelBuilding = true;
passthru.tests = { inherit (nixosTests) frr; };
meta = with lib; {
description = "FRR BGP/OSPF/ISIS/RIP/RIPNG routing daemon suite";
longDescription = ''
FRRouting (FRR) is a free and open source Internet routing protocol suite
for Linux and Unix platforms. It implements BGP, OSPF, RIP, IS-IS, PIM,
LDP, BFD, Babel, PBR, OpenFabric and VRRP, with alpha support for EIGRP
and NHRP.
FRRs seamless integration with native Linux/Unix IP networking stacks
makes it a general purpose routing stack applicable to a wide variety of
use cases including connecting hosts/VMs/containers to the network,
advertising network services, LAN switching and routing, Internet access
routers, and Internet peering.
FRR has its roots in the Quagga project. In fact, it was started by many
long-time Quagga developers who combined their efforts to improve on
Quaggas well-established foundation in order to create the best routing
protocol stack available. We invite you to participate in the FRRouting
community and help shape the future of networking.
Join the ranks of network architects using FRR for ISPs, SaaS
infrastructure, web 2.0 businesses, hyperscale services, and Fortune 500
private clouds.
'';
homepage = "https://frrouting.org/";
license = with licenses; [ gpl2Plus lgpl21Plus ];
platforms = platforms.unix;
maintainers = with maintainers; [ woffs ];
};
}

View File

@ -5321,6 +5321,8 @@ with pkgs;
flvstreamer = callPackage ../tools/networking/flvstreamer { };
frr = callPackage ../servers/frr { };
hmetis = pkgsi686Linux.callPackage ../applications/science/math/hmetis { };
libbsd = callPackage ../development/libraries/libbsd { };
@ -18700,6 +18702,8 @@ with pkgs;
libyamlcpp_0_3 = callPackage ../development/libraries/libyaml-cpp/0.3.0.nix { };
libyang = callPackage ../development/libraries/libyang { };
libcyaml = callPackage ../development/libraries/libcyaml { };
rang = callPackage ../development/libraries/rang { };