Compare commits

...

8 Commits

Author SHA1 Message Date
db03284752 Move dn42.nix into modules/default.nix 2024-03-12 00:23:19 +01:00
8b67ea43c1 Add checks/two-peers 2024-03-12 00:21:11 +01:00
625b66e814 Add peer srcAddr 2024-03-12 00:20:15 +01:00
1a4a6f0e8d Replace peer asn with as 2024-03-11 23:07:28 +01:00
479428b421 Fix concatMapStringsSep usage 2024-03-11 23:06:46 +01:00
492575a245 Make description more precise about accepted format 2024-03-11 23:06:40 +01:00
eeb9ec7de3 Fix nets.v6 2024-03-11 23:05:12 +01:00
309354be1e Let routerId default to addr.v4 2024-03-11 23:04:11 +01:00
3 changed files with 161 additions and 12 deletions

117
checks/two-peers.nix Normal file
View File

@ -0,0 +1,117 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.nixosTest rec {
name = "two-peers";
nodes = {
foo = {
imports = [ ../modules ];
networking.dn42 = {
enable = true;
as = 64600;
addr.v4 = "172.20.0.1";
nets.v4 = [ "172.20.0.0/24" ];
addr.v6 = "fec0::1";
nets.v6 = [ "fec0::/64" ];
peers.bar = {
as = 64601;
addr.v4 = (builtins.head nodes.bar.networking.interfaces.enp1s0.ipv4.addresses).address;
addr.v6 = (builtins.head nodes.bar.networking.interfaces.enp1s0.ipv6.addresses).address;
srcAddr.v4 = (builtins.head nodes.foo.networking.interfaces.enp1s0.ipv4.addresses).address;
srcAddr.v6 = (builtins.head nodes.foo.networking.interfaces.enp1s0.ipv6.addresses).address;
interface = "enp1s0";
};
};
virtualisation.interfaces.enp1s0.vlan = 2;
networking.useNetworkd = true;
systemd.network.netdevs.dummy0.netdevConfig = {
Kind = "dummy";
Name = "dummy0";
};
networking.interfaces.enp1s0 = {
ipv4.addresses = [ {
address = "10.0.0.1";
prefixLength = 24;
} ];
ipv6.addresses = [ {
address = "fe80::1";
prefixLength = 64;
} ];
};
networking.interfaces.dummy0 = {
ipv4.addresses = [ {
address = nodes.foo.networking.dn42.addr.v4;
prefixLength = 24;
} ];
ipv6.addresses = [ {
address = nodes.foo.networking.dn42.addr.v6;
prefixLength = 64;
} ];
};
networking.firewall.enable = false;
};
bar = {
imports = [ ../modules ];
networking.dn42 = {
enable = true;
as = 64601;
addr.v4 = "172.20.1.1";
nets.v4 = [ "172.20.1.0/24" ];
addr.v6 = "fec0:0:0:1::1";
nets.v6 = [ "fec0:0:0:1::/64" ];
peers.foo = {
as = 64600;
addr.v4 = (builtins.head nodes.foo.networking.interfaces.enp1s0.ipv4.addresses).address;
addr.v6 = (builtins.head nodes.foo.networking.interfaces.enp1s0.ipv6.addresses).address;
srcAddr.v4 = (builtins.head nodes.bar.networking.interfaces.enp1s0.ipv4.addresses).address;
srcAddr.v6 = (builtins.head nodes.bar.networking.interfaces.enp1s0.ipv6.addresses).address;
interface = "enp1s0";
};
};
virtualisation.interfaces.enp1s0.vlan = 2;
networking.useNetworkd = true;
systemd.network.netdevs.dummy0.netdevConfig = {
Kind = "dummy";
Name = "dummy0";
};
networking.interfaces.enp1s0 = {
ipv4.addresses = [ {
address = "10.0.0.2";
prefixLength = 24;
} ];
ipv6.addresses = [ {
address = "fe80::2";
prefixLength = 64;
} ];
};
networking.interfaces.dummy0 = {
ipv4.addresses = [ {
address = nodes.bar.networking.dn42.addr.v4;
prefixLength = 24;
} ];
ipv6.addresses = [ {
address = nodes.bar.networking.dn42.addr.v6;
prefixLength = 64;
} ];
};
networking.firewall.enable = false;
};
};
testScript = ''
foo.wait_for_unit("bird2")
bar.wait_for_unit("bird2")
# Test basic reachability on the peering network
foo.wait_until_succeeds("ping -c 1 10.0.0.2")
bar.wait_until_succeeds("ping -c 1 10.0.0.1")
# Assuming IPv4 peering is up, try ping on routed dummy0 addrs
foo.wait_until_succeeds("ping -c 1 ${nodes.bar.networking.dn42.addr.v4}")
bar.wait_until_succeeds("ping -c 1 ${nodes.foo.networking.dn42.addr.v4}")
# icmpv6 unsupported by QEMU user networking
# foo.wait_until_succeeds("ping -c 1 ${nodes.bar.networking.dn42.addr.v6}")
# bar.wait_until_succeeds("ping -c 1 ${nodes.foo.networking.dn42.addr.v6}")
'';
}

View File

@ -1,8 +1,21 @@
{ {
outputs = { ... }: { outputs = { self, nixpkgs, ... }:
nixosModules = rec { let
dn42 = import ./dn42.nix; systems = [ "x86_64-linux" "aarch64-linux" ];
default = dn42;
in {
nixosModules = rec {
dn42 = import ./modules;
default = dn42;
};
checks = builtins.listToAttrs (map (system: {
name = system;
value = {
two-peers = import ./checks/two-peers.nix {
pkgs = nixpkgs.legacyPackages.${system};
};
};
}) systems);
}; };
};
} }

View File

@ -9,6 +9,7 @@ in
routerId = lib.mkOption { routerId = lib.mkOption {
type = lib.types.str; type = lib.types.str;
description = "32bit router identifier."; description = "32bit router identifier.";
default = cfg.addr.v4;
}; };
as = lib.mkOption { as = lib.mkOption {
@ -31,12 +32,12 @@ in
nets = { nets = {
v4 = lib.mkOption { v4 = lib.mkOption {
type = with lib.types; listOf str; type = with lib.types; listOf str;
description = "Own IPv4 net"; description = "Own IPv4 networks, list of CIDR";
}; };
v6 = lib.mkOption { v6 = lib.mkOption {
type = with lib.types; listOf str; type = with lib.types; listOf str;
description = "Own IPv6 net"; description = "Own IPv6 networks, list of CIDR";
}; };
}; };
@ -64,6 +65,18 @@ in
description = "IPv6 address of the peer."; description = "IPv6 address of the peer.";
}; };
}; };
srcAddr = {
v4 = lib.mkOption {
type = with lib.types; nullOr str;
description = "Local IPv4 address to use for BGP.";
};
v6 = lib.mkOption {
type = with lib.types; nullOr str;
description = "Local IPv6 address to use for BGP.";
};
};
}; };
})); }));
}; };
@ -87,7 +100,7 @@ in
function is_self_net_v4() -> bool { function is_self_net_v4() -> bool {
return ${if cfg.nets.v4 == [] return ${if cfg.nets.v4 == []
then "false" then "false"
else builtins.concatMapStringsSep " || " (net: else lib.concatMapStringsSep " || " (net:
"net ~ ${net}" "net ~ ${net}"
) cfg.nets.v4}; ) cfg.nets.v4};
} }
@ -95,7 +108,7 @@ in
function is_self_net_v6() -> bool { function is_self_net_v6() -> bool {
return ${if cfg.nets.v4 == [] return ${if cfg.nets.v4 == []
then "false" then "false"
else builtins.concatMapStringsSep " || " (net: else lib.concatMapStringsSep " || " (net:
"net ~ ${net}" "net ~ ${net}"
) cfg.nets.v6}; ) cfg.nets.v6};
} }
@ -175,7 +188,7 @@ in
protocol static { protocol static {
${lib.concatMapStrings (net: '' ${lib.concatMapStrings (net: ''
route ${net} reject; route ${net} reject;
'') cfg.nets.v4} '') cfg.nets.v6}
ipv6 { ipv6 {
import all; import all;
@ -221,11 +234,17 @@ in
(builtins.mapAttrs (builtins.mapAttrs
(name: conf: '' (name: conf: ''
protocol bgp ${name}_4 from dnpeers { protocol bgp ${name}_4 from dnpeers {
neighbor ${conf.addr.v4} as ${builtins.toString conf.asn}; neighbor ${conf.addr.v4} as ${builtins.toString conf.as};
${lib.optionalString (conf.srcAddr.v4 != null) ''
source address ${conf.srcAddr.v4};
''}
} }
protocol bgp ${name}_6 from dnpeers { protocol bgp ${name}_6 from dnpeers {
neighbor ${conf.addr.v6}%${conf.interface} as ${builtins.toString conf.asn}; neighbor ${conf.addr.v6}%${conf.interface} as ${builtins.toString conf.as};
${lib.optionalString (conf.srcAddr.v6 != null) ''
source address ${conf.srcAddr.v6};
''}
} }
'') '')
cfg.peers))} cfg.peers))}