diff --git a/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
index c0f407e11a9..023f0f57a9b 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
@@ -1548,6 +1548,12 @@ Superuser created successfully.
Foo-over-UDP encapsulations.
+
+
+ networking.sits now supports Foo-over-UDP
+ encapsulation.
+
+
diff --git a/nixos/doc/manual/release-notes/rl-2111.section.md b/nixos/doc/manual/release-notes/rl-2111.section.md
index 6dadcde3ccc..658f3b59da6 100644
--- a/nixos/doc/manual/release-notes/rl-2111.section.md
+++ b/nixos/doc/manual/release-notes/rl-2111.section.md
@@ -447,3 +447,5 @@ In addition to numerous new and upgraded packages, this release has the followin
- The `systemd.network` module has gained support for the FooOverUDP link type.
- The `networking` module has a new `networking.fooOverUDP` option to configure Foo-over-UDP encapsulations.
+
+- `networking.sits` now supports Foo-over-UDP encapsulation.
diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix
index 055580e3ea2..e8e2de090b3 100644
--- a/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -519,7 +519,12 @@ let
${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.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 set "${n}" up
'';
postStop = ''
diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix
index 516764b87db..ccfd7fd4132 100644
--- a/nixos/modules/tasks/network-interfaces-systemd.nix
+++ b/nixos/modules/tasks/network-interfaces-systemd.nix
@@ -227,7 +227,17 @@ in
Local = sit.local;
}) // (optionalAttrs (sit.ttl != null) {
TTL = sit.ttl;
- });
+ }) // (optionalAttrs (sit.encapsulation != null) (
+ {
+ FooOverUDP = true;
+ Encapsulation =
+ if sit.encapsulation.type == "fou"
+ then "FooOverUDP"
+ else "GenericUDPEncapsulation";
+ FOUDestinationPort = sit.encapsulation.port;
+ } // (optionalAttrs (sit.encapsulation.sourcePort != null) {
+ FOUSourcePort = sit.encapsulation.sourcePort;
+ })));
};
networks = mkIf (sit.dev != null) {
"40-${sit.dev}" = (mkMerge [ (genericNetwork (mkOverride 999)) {
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index a3b41326168..4e20ec11846 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -10,7 +10,8 @@ let
hasVirtuals = any (i: i.virtual) interfaces;
hasSits = cfg.sits != { };
hasBonds = cfg.bonds != { };
- hasFous = cfg.fooOverUDP != { };
+ hasFous = cfg.fooOverUDP != { }
+ || filterAttrs (_: s: s.encapsulation != null) cfg.sits != { };
slaves = concatMap (i: i.interfaces) (attrValues cfg.bonds)
++ concatMap (i: i.interfaces) (attrValues cfg.bridges)
@@ -948,6 +949,44 @@ in
'';
};
+ encapsulation = with types; mkOption {
+ type = nullOr (submodule {
+ options = {
+ type = mkOption {
+ type = enum [ "fou" "gue" ];
+ description = ''
+ Selects encapsulation type. See
+ ip-link
+ 8 for details.
+ '';
+ };
+
+ port = mkOption {
+ type = port;
+ example = 9001;
+ description = ''
+ Destination port for encapsulated packets.
+ '';
+ };
+
+ sourcePort = mkOption {
+ type = nullOr types.port;
+ default = null;
+ example = 9002;
+ description = ''
+ Source port for encapsulated packets. Will be chosen automatically by
+ the kernel if unset.
+ '';
+ };
+ };
+ });
+ default = null;
+ example = { type = "fou"; port = 9001; };
+ description = ''
+ Configures encapsulation in UDP packets.
+ '';
+ };
+
};
});
diff --git a/nixos/tests/networking.nix b/nixos/tests/networking.nix
index fdcf67f1126..647c8942b37 100644
--- a/nixos/tests/networking.nix
+++ b/nixos/tests/networking.nix
@@ -431,7 +431,6 @@ let
virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = networkd;
- firewall.enable = false;
useDHCP = false;
sits.sit = {
inherit remote;
@@ -446,8 +445,30 @@ let
};
in {
name = "Sit";
- nodes.client1 = node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; };
- nodes.client2 = node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; };
+ # note on firewalling: the two nodes are explicitly asymmetric.
+ # client1 sends SIT packets in UDP, but accepts only proto-41 incoming.
+ # client2 does the reverse, sending in proto-41 and accepting only UDP incoming.
+ # that way we'll notice when either SIT itself or FOU breaks.
+ nodes.client1 = args@{ pkgs, ... }:
+ mkMerge [
+ (node { address4 = "192.168.1.1"; remote = "192.168.1.2"; address6 = "fc00::1"; } args)
+ {
+ networking = {
+ firewall.extraCommands = "iptables -A INPUT -p 41 -j ACCEPT";
+ sits.sit.encapsulation = { type = "fou"; port = 9001; };
+ };
+ }
+ ];
+ nodes.client2 = args@{ pkgs, ... }:
+ mkMerge [
+ (node { address4 = "192.168.1.2"; remote = "192.168.1.1"; address6 = "fc00::2"; } args)
+ {
+ networking = {
+ firewall.allowedUDPPorts = [ 9001 ];
+ fooOverUDP.fou1 = { port = 9001; protocol = 41; };
+ };
+ }
+ ];
testScript = { ... }:
''
start_all()