From 716634530e39e0423f038b464bc61427db6e4707 Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Sun, 15 Jun 2025 16:55:28 +0200 Subject: [PATCH] nixos/networking-interfaces: clean up networking.sits This change rework a bit the documentation on networking.sits to explain what they actually are. In fact, there are three different protocols being collectively called "SIT", which itself is a nonstandard term. --- .../tasks/network-interfaces-scripted.nix | 25 ++++--- .../tasks/network-interfaces-systemd.nix | 2 +- nixos/modules/tasks/network-interfaces.nix | 74 +++++++++++++------ 3 files changed, 65 insertions(+), 36 deletions(-) diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index 69959e650a14..0634f661c12a 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -627,7 +627,7 @@ let deps = deviceDependency v.dev; in { - description = "6-to-4 Tunnel Interface ${n}"; + description = "IPv6 in IPv4 Tunnel Interface ${n}"; wantedBy = [ "network-setup.service" (subsystemDevice n) @@ -641,18 +641,19 @@ let script = '' # Remove Dead Interfaces ip link show dev "${n}" >/dev/null 2>&1 && ip link delete dev "${n}" - ip link add name "${n}" type sit \ - ${optionalString (v.remote != null) "remote \"${v.remote}\""} \ - ${optionalString (v.local != null) "local \"${v.local}\""} \ - ${optionalString (v.ttl != null) "ttl ${toString v.ttl}"} \ - ${optionalString (v.dev != null) "dev \"${v.dev}\""} \ - ${optionalString (v.encapsulation != null) - "encap ${v.encapsulation.type} encap-dport ${toString v.encapsulation.port} ${ - optionalString ( - v.encapsulation.sourcePort != null - ) "encap-sport ${toString v.encapsulation.sourcePort}" - }" + ip link add name "${n}" type sit ${ + formatIpArgs { + inherit (v) + remote + local + ttl + dev + ; + encap = if v.encapsulation.type == "6in4" then null else v.encapsulation.type; + encap-dport = v.encapsulation.port; + encap-sport = v.encapsulation.sourcePort; } + } ip link set dev "${n}" up ''; postStop = '' diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix index 574c558b8900..072ed080595e 100644 --- a/nixos/modules/tasks/network-interfaces-systemd.nix +++ b/nixos/modules/tasks/network-interfaces-systemd.nix @@ -438,7 +438,7 @@ in // (optionalAttrs (sit.ttl != null) { TTL = sit.ttl; }) - // (optionalAttrs (sit.encapsulation != null) ( + // (optionalAttrs (sit.encapsulation.type != "6in4") ( { FooOverUDP = true; Encapsulation = if sit.encapsulation.type == "fou" then "FooOverUDP" else "GenericUDPEncapsulation"; diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 2f10bf2ec8be..86b2f42e5075 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -19,7 +19,8 @@ let hasSits = cfg.sits != { }; hasGres = cfg.greTunnels != { }; hasBonds = cfg.bonds != { }; - hasFous = cfg.fooOverUDP != { } || filterAttrs (_: s: s.encapsulation != null) cfg.sits != { }; + hasFous = + cfg.fooOverUDP != { } || filterAttrs (_: s: s.encapsulation.type != "6in4") cfg.sits != { }; slaves = concatMap (i: i.interfaces) (attrValues cfg.bonds) @@ -1153,7 +1154,8 @@ in } ''; description = '' - This option allows you to define 6-to-4 interfaces which should be automatically created. + This option allows you to define interfaces encapsulating IPv6 + packets within IPv4 packets; which should be automatically created. ''; type = with types; @@ -1197,50 +1199,76 @@ in ''; }; - encapsulation = - with types; - mkOption { - type = nullOr (submodule { + encapsulation = mkOption { + type = types.nullOr ( + types.submodule { options = { type = mkOption { - type = enum [ + type = types.enum [ + "6in4" "fou" "gue" ]; + default = "6in4"; description = '' - Selects encapsulation type. See - {manpage}`ip-link(8)` for details. + Select the encapsulation type: + + - `6in4`: the IPv6 packets are encapsulated using the + 6in4 protocol (formerly known as SIT, RFC 4213); + + - `gue`: the IPv6 packets are encapsulated in UDP packets + using the Generic UDP Encapsulation (GUE) scheme; + + - `foo`: the IPv6 packets are encapsulated in UDP packets + using the Foo over UDP (FOU) scheme. ''; }; port = mkOption { - type = port; + type = types.nullOr types.port; + default = null; example = 9001; description = '' - Destination port for encapsulated packets. + Destination port when using UDP encapsulation. ''; }; sourcePort = mkOption { - type = nullOr types.port; + type = types.nullOr types.port; default = null; example = 9002; description = '' - Source port for encapsulated packets. Will be chosen automatically by - the kernel if unset. + Source port when using UDP encapsulation. + Will be chosen automatically by the kernel if unset. ''; }; }; - }); - default = null; - example = { - type = "fou"; - port = 9001; - }; - description = '' - Configures encapsulation in UDP packets. - ''; + } + ); + apply = + x: + if x == null then + lib.warn + '' + The option networking.sits.*.encapsulation no longer accepts `null` + as a valid value. To fix this warning simply remove this definition. + '' + { + type = "6in4"; + port = null; + sourcePort = null; + } + else + x; + default = { }; + example = { + type = "fou"; + port = 9001; }; + description = '' + Configures the type of encapsulation. + ''; + }; };