mirror of
https://git.sr.ht/~magic_rb/dotfiles
synced 2024-12-13 02:12:00 +01:00
90 lines
2.1 KiB
Nix
90 lines
2.1 KiB
Nix
|
{
|
||
|
config,
|
||
|
lib,
|
||
|
pkgs,
|
||
|
...
|
||
|
}: let
|
||
|
inherit
|
||
|
(lib)
|
||
|
mkOption
|
||
|
mkIf
|
||
|
mkMerge
|
||
|
types
|
||
|
getExe'
|
||
|
flip
|
||
|
mapAttrs'
|
||
|
flatten
|
||
|
mapAttrsToList
|
||
|
nameValuePair
|
||
|
concatMapStringsSep
|
||
|
mkEnableOption
|
||
|
;
|
||
|
|
||
|
cfg = config.networking.netnsIf;
|
||
|
in {
|
||
|
options.networking.netnsIf = {
|
||
|
assignments = mkOption {
|
||
|
description = ''
|
||
|
Assign network interfaces to a network namespaces by MAC address.
|
||
|
'';
|
||
|
type = types.attrsOf (types.listOf types.str);
|
||
|
default = {};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
config =
|
||
|
mkIf (cfg.assignments != {})
|
||
|
{
|
||
|
systemd.services = mkMerge [
|
||
|
{
|
||
|
"netns@" = {
|
||
|
description = "Ensure the %I network namespace exists";
|
||
|
|
||
|
serviceConfig = {
|
||
|
Type = "oneshot";
|
||
|
};
|
||
|
|
||
|
scriptArgs = "%I";
|
||
|
script = ''
|
||
|
set -eo pipefail
|
||
|
_network_namespace="$1"
|
||
|
|
||
|
if ! [ -n "$(${getExe' pkgs.iproute2 "ip"} netns list | grep "$_network_namespace")" ] ; then
|
||
|
${getExe' pkgs.iproute2 "ip"} netns add "$_network_namespace"
|
||
|
fi
|
||
|
'';
|
||
|
};
|
||
|
}
|
||
|
|
||
|
(flip mapAttrs' cfg.assignments (n: _:
|
||
|
nameValuePair "netns-${n}-if@" {
|
||
|
description = "Move %I interface to namespace";
|
||
|
requires = ["netns@${n}.service"];
|
||
|
after = ["netns@${n}.service"];
|
||
|
|
||
|
scriptArgs = "%I";
|
||
|
script = ''
|
||
|
set -eo pipefail
|
||
|
_kernel_name="$(basename "$1")"
|
||
|
|
||
|
${getExe' pkgs.iproute2 "ip"} link set "$_kernel_name" netns "${n}"
|
||
|
'';
|
||
|
}))
|
||
|
];
|
||
|
|
||
|
services.udev.extraRules =
|
||
|
flip (concatMapStringsSep "\n") (flatten (mapAttrsToList (n: v:
|
||
|
map (x: {
|
||
|
interface = x;
|
||
|
namespace = n;
|
||
|
})
|
||
|
v)
|
||
|
cfg.assignments)) ({
|
||
|
interface,
|
||
|
namespace,
|
||
|
}: ''
|
||
|
SUBSYSTEM=="net", ACTION=="add", DEVPATH!="/devices/virtual/*", ATTR{address}=="${interface}", TAG+="systemd", ENV{SYSTEMD_WANTS}="netns-${namespace}-if@.service"
|
||
|
'');
|
||
|
};
|
||
|
}
|