mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-07-13 21:50:33 +03:00
Merge pull request #81405 from NinjaTrappeur/nin-networkd-policy-rules
nixos/networkd: add RoutingPolicyRules-related options
This commit is contained in:
commit
7f9131f260
4 changed files with 101 additions and 6 deletions
|
@ -67,7 +67,12 @@ let
|
||||||
(assertOnlyFields [
|
(assertOnlyFields [
|
||||||
"PrivateKeyFile" "ListenPort" "FwMark"
|
"PrivateKeyFile" "ListenPort" "FwMark"
|
||||||
])
|
])
|
||||||
(assertRange "FwMark" 1 4294967295)
|
# The following check won't work on nix <= 2.2
|
||||||
|
# see https://github.com/NixOS/nix/pull/2378
|
||||||
|
#
|
||||||
|
# Add this again when we'll have drop the
|
||||||
|
# nix < 2.2 support.
|
||||||
|
# (assertRange "FwMark" 1 4294967295)
|
||||||
];
|
];
|
||||||
|
|
||||||
# NOTE The PresharedKey directive is missing on purpose here, please
|
# NOTE The PresharedKey directive is missing on purpose here, please
|
||||||
|
@ -181,7 +186,12 @@ let
|
||||||
(assertOnlyFields [
|
(assertOnlyFields [
|
||||||
"InterfaceId" "Independent"
|
"InterfaceId" "Independent"
|
||||||
])
|
])
|
||||||
(assertRange "InterfaceId" 1 4294967295)
|
# The following check won't work on nix <= 2.2
|
||||||
|
# see https://github.com/NixOS/nix/pull/2378
|
||||||
|
#
|
||||||
|
# Add this again when we'll have drop the
|
||||||
|
# nix < 2.2 support.
|
||||||
|
# (assertRange "InterfaceId" 1 4294967295)
|
||||||
(assertValueOneOf "Independent" boolValues)
|
(assertValueOneOf "Independent" boolValues)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -235,6 +245,26 @@ let
|
||||||
(assertValueOneOf "AutoJoin" boolValues)
|
(assertValueOneOf "AutoJoin" boolValues)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
checkRoutingPolicyRule = checkUnitConfig "RoutingPolicyRule" [
|
||||||
|
(assertOnlyFields [
|
||||||
|
"TypeOfService" "From" "To" "FirewallMark" "Table" "Priority"
|
||||||
|
"IncomingInterface" "OutgoingInterface" "SourcePort" "DestinationPort"
|
||||||
|
"IPProtocol" "InvertRule" "Family"
|
||||||
|
])
|
||||||
|
(assertRange "TypeOfService" 0 255)
|
||||||
|
# The following check won't work on nix <= 2.2
|
||||||
|
# see https://github.com/NixOS/nix/pull/2378
|
||||||
|
#
|
||||||
|
# Add this again when we'll have drop the
|
||||||
|
# nix < 2.2 support.
|
||||||
|
# (assertRange "FirewallMark" 1 4294967295)
|
||||||
|
(assertInt "Priority")
|
||||||
|
(assertPort "SourcePort")
|
||||||
|
(assertPort "DestinationPort")
|
||||||
|
(assertValueOneOf "InvertRule" boolValues)
|
||||||
|
(assertValueOneOf "Family" ["ipv4" "ipv6" "both"])
|
||||||
|
];
|
||||||
|
|
||||||
checkRoute = checkUnitConfig "Route" [
|
checkRoute = checkUnitConfig "Route" [
|
||||||
(assertOnlyFields [
|
(assertOnlyFields [
|
||||||
"Gateway" "GatewayOnLink" "Destination" "Source" "Metric"
|
"Gateway" "GatewayOnLink" "Destination" "Source" "Metric"
|
||||||
|
@ -535,6 +565,22 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
routingPolicyRulesOptions = {
|
||||||
|
options = {
|
||||||
|
routingPolicyRuleConfig = mkOption {
|
||||||
|
default = { };
|
||||||
|
example = { routingPolicyRuleConfig = { Table = 10; IncomingInterface = "eth1"; Family = "both"; } ;};
|
||||||
|
type = types.addCheck (types.attrsOf unitOption) checkRoutingPolicyRule;
|
||||||
|
description = ''
|
||||||
|
Each attribute in this set specifies an option in the
|
||||||
|
<literal>[RoutingPolicyRule]</literal> section of the unit. See
|
||||||
|
<citerefentry><refentrytitle>systemd.network</refentrytitle>
|
||||||
|
<manvolnum>5</manvolnum></citerefentry> for details.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
routeOptions = {
|
routeOptions = {
|
||||||
options = {
|
options = {
|
||||||
routeConfig = mkOption {
|
routeConfig = mkOption {
|
||||||
|
@ -772,6 +818,16 @@ let
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
routingPolicyRules = mkOption {
|
||||||
|
default = [ ];
|
||||||
|
type = with types; listOf (submodule routingPolicyRulesOptions);
|
||||||
|
description = ''
|
||||||
|
A list of routing policy rules sections to be added to the unit. See
|
||||||
|
<citerefentry><refentrytitle>systemd.network</refentrytitle>
|
||||||
|
<manvolnum>5</manvolnum></citerefentry> for details.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
routes = mkOption {
|
routes = mkOption {
|
||||||
default = [ ];
|
default = [ ];
|
||||||
type = with types; listOf (submodule routeOptions);
|
type = with types; listOf (submodule routeOptions);
|
||||||
|
@ -928,6 +984,11 @@ let
|
||||||
[Route]
|
[Route]
|
||||||
${attrsToSection x.routeConfig}
|
${attrsToSection x.routeConfig}
|
||||||
|
|
||||||
|
'')}
|
||||||
|
${flip concatMapStrings def.routingPolicyRules (x: ''
|
||||||
|
[RoutingPolicyRule]
|
||||||
|
${attrsToSection x.routingPolicyRuleConfig}
|
||||||
|
|
||||||
'')}
|
'')}
|
||||||
${def.extraConfig}
|
${def.extraConfig}
|
||||||
'';
|
'';
|
||||||
|
|
|
@ -59,6 +59,11 @@ in rec {
|
||||||
optional (attr ? ${name} && ! isMacAddress attr.${name})
|
optional (attr ? ${name} && ! isMacAddress attr.${name})
|
||||||
"Systemd ${group} field `${name}' must be a valid mac address.";
|
"Systemd ${group} field `${name}' must be a valid mac address.";
|
||||||
|
|
||||||
|
isPort = i: i >= 0 && i <= 65535;
|
||||||
|
|
||||||
|
assertPort = name: group: attr:
|
||||||
|
optional (attr ? ${name} && ! isPort attr.${name})
|
||||||
|
"Error on the systemd ${group} field `${name}': ${attr.name} is not a valid port number.";
|
||||||
|
|
||||||
assertValueOneOf = name: values: group: attr:
|
assertValueOneOf = name: values: group: attr:
|
||||||
optional (attr ? ${name} && !elem attr.${name} values)
|
optional (attr ? ${name} && !elem attr.${name} values)
|
||||||
|
|
|
@ -285,7 +285,7 @@ in
|
||||||
systemd-confinement = handleTest ./systemd-confinement.nix {};
|
systemd-confinement = handleTest ./systemd-confinement.nix {};
|
||||||
systemd-timesyncd = handleTest ./systemd-timesyncd.nix {};
|
systemd-timesyncd = handleTest ./systemd-timesyncd.nix {};
|
||||||
systemd-networkd-vrf = handleTest ./systemd-networkd-vrf.nix {};
|
systemd-networkd-vrf = handleTest ./systemd-networkd-vrf.nix {};
|
||||||
systemd-networkd-wireguard = handleTest ./systemd-networkd-wireguard.nix {};
|
systemd-networkd = handleTest ./systemd-networkd.nix {};
|
||||||
systemd-nspawn = handleTest ./systemd-nspawn.nix {};
|
systemd-nspawn = handleTest ./systemd-nspawn.nix {};
|
||||||
pdns-recursor = handleTest ./pdns-recursor.nix {};
|
pdns-recursor = handleTest ./pdns-recursor.nix {};
|
||||||
taskserver = handleTest ./taskserver.nix {};
|
taskserver = handleTest ./taskserver.nix {};
|
||||||
|
|
|
@ -41,15 +41,25 @@ let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: {
|
||||||
{ routeConfig = { Gateway = "10.0.0.${nodeId}"; Destination = "10.0.0.0/24"; }; }
|
{ routeConfig = { Gateway = "10.0.0.${nodeId}"; Destination = "10.0.0.0/24"; }; }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
"90-eth1" = {
|
"30-eth1" = {
|
||||||
matchConfig = { Name = "eth1"; };
|
matchConfig = { Name = "eth1"; };
|
||||||
address = [ "192.168.1.${nodeId}/24" ];
|
address = [
|
||||||
|
"192.168.1.${nodeId}/24"
|
||||||
|
"fe80::${nodeId}/64"
|
||||||
|
];
|
||||||
|
routingPolicyRules = [
|
||||||
|
{ routingPolicyRuleConfig = { Table = 10; IncomingInterface = "eth1"; Family = "both"; };}
|
||||||
|
{ routingPolicyRuleConfig = { Table = 20; OutgoingInterface = "eth1"; };}
|
||||||
|
{ routingPolicyRuleConfig = { Table = 30; From = "192.168.1.1"; To = "192.168.1.2"; SourcePort = 666 ; DestinationPort = 667; };}
|
||||||
|
{ routingPolicyRuleConfig = { Table = 40; IPProtocol = "tcp"; InvertRule = true; };}
|
||||||
|
{ routingPolicyRuleConfig = { Table = 50; IncomingInterface = "eth1"; Family = "ipv4"; };}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in import ./make-test-python.nix ({pkgs, ... }: {
|
in import ./make-test-python.nix ({pkgs, ... }: {
|
||||||
name = "networkd-wireguard";
|
name = "networkd";
|
||||||
meta = with pkgs.stdenv.lib.maintainers; {
|
meta = with pkgs.stdenv.lib.maintainers; {
|
||||||
maintainers = [ ninjatrappeur ];
|
maintainers = [ ninjatrappeur ];
|
||||||
};
|
};
|
||||||
|
@ -76,9 +86,28 @@ testScript = ''
|
||||||
start_all()
|
start_all()
|
||||||
node1.wait_for_unit("systemd-networkd-wait-online.service")
|
node1.wait_for_unit("systemd-networkd-wait-online.service")
|
||||||
node2.wait_for_unit("systemd-networkd-wait-online.service")
|
node2.wait_for_unit("systemd-networkd-wait-online.service")
|
||||||
|
|
||||||
|
# ================================
|
||||||
|
# Wireguard
|
||||||
|
# ================================
|
||||||
node1.succeed("ping -c 5 10.0.0.2")
|
node1.succeed("ping -c 5 10.0.0.2")
|
||||||
node2.succeed("ping -c 5 10.0.0.1")
|
node2.succeed("ping -c 5 10.0.0.1")
|
||||||
# Is the fwmark set?
|
# Is the fwmark set?
|
||||||
node2.succeed("wg | grep -q 42")
|
node2.succeed("wg | grep -q 42")
|
||||||
|
|
||||||
|
# ================================
|
||||||
|
# Routing Policies
|
||||||
|
# ================================
|
||||||
|
# Testing all the routingPolicyRuleConfig members:
|
||||||
|
# Table + IncomingInterface
|
||||||
|
node1.succeed("sudo ip rule | grep 'from all iif eth1 lookup 10'")
|
||||||
|
# OutgoingInterface
|
||||||
|
node1.succeed("sudo ip rule | grep 'from all oif eth1 lookup 20'")
|
||||||
|
# From + To + SourcePort + DestinationPort
|
||||||
|
node1.succeed(
|
||||||
|
"sudo ip rule | grep 'from 192.168.1.1 to 192.168.1.2 sport 666 dport 667 lookup 30'"
|
||||||
|
)
|
||||||
|
# IPProtocol + InvertRule
|
||||||
|
node1.succeed("sudo ip rule | grep 'not from all ipproto tcp lookup 40'")
|
||||||
'';
|
'';
|
||||||
})
|
})
|
Loading…
Add table
Add a link
Reference in a new issue