summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.network.xml7
-rw-r--r--src/network/networkd-link.c6
-rw-r--r--src/network/networkd-manager.c4
-rw-r--r--src/network/networkd.h1
4 files changed, 15 insertions, 3 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index bd061c270a..54fef4c9c4 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -366,7 +366,8 @@
the routing table. Takes either a boolean argument, or the
values <literal>ipv4</literal> or <literal>ipv6</literal>,
which only enables IP forwarding for the specified address
- family. This controls the
+ family, or <literal>kernel</literal>, which preserves existing sysctl settings.
+ This controls the
<filename>net.ipv4.conf.&lt;interface&gt;.forwarding</filename>
and
<filename>net.ipv6.conf.&lt;interface&gt;.forwarding</filename>
@@ -375,8 +376,8 @@
for details about sysctl options). Defaults to
<literal>no</literal>.</para>
- <para>Note: unless this option is turned on, no IP
- forwarding is done on this interface, even if this is
+ <para>Note: unless this option is turned on, or set to <literal>kernel</literal>,
+ no IP forwarding is done on this interface, even if this is
globally turned on in the kernel, with the
<filename>net.ipv4.ip_forward</filename> and
<filename>net.ipv4.ip_forward</filename> sysctl
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index f039a2d687..b30fd7ae89 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1481,6 +1481,9 @@ static int link_set_ipv4_forward(Link *link) {
const char *p = NULL;
int r;
+ if (link->network->ip_forward == ADDRESS_FAMILY_KERNEL)
+ return 0;
+
p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/forwarding");
r = write_string_file_no_create(p, one_zero(link_ipv4_forward_enabled(link)));
if (r < 0)
@@ -1497,6 +1500,9 @@ static int link_set_ipv6_forward(Link *link) {
if (!socket_ipv6_is_supported())
return 0;
+ if (link->network->ip_forward == ADDRESS_FAMILY_KERNEL)
+ return 0;
+
p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/forwarding");
r = write_string_file_no_create(p, one_zero(link_ipv6_forward_enabled(link)));
if (r < 0)
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index db737ad484..2cc53df4b1 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -853,6 +853,8 @@ const char *address_family_boolean_to_string(AddressFamilyBoolean b) {
return "ipv4";
if (b == ADDRESS_FAMILY_IPV6)
return "ipv6";
+ if (b == ADDRESS_FAMILY_KERNEL)
+ return "kernel";
return NULL;
}
@@ -872,6 +874,8 @@ AddressFamilyBoolean address_family_boolean_from_string(const char *s) {
return ADDRESS_FAMILY_IPV4;
if (streq(s, "ipv6"))
return ADDRESS_FAMILY_IPV6;
+ if (streq(s, "kernel"))
+ return ADDRESS_FAMILY_KERNEL;
return _ADDRESS_FAMILY_BOOLEAN_INVALID;
}
diff --git a/src/network/networkd.h b/src/network/networkd.h
index 4b13d4aed1..49afeffe81 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -60,6 +60,7 @@ typedef enum AddressFamilyBoolean {
ADDRESS_FAMILY_IPV4 = 1,
ADDRESS_FAMILY_IPV6 = 2,
ADDRESS_FAMILY_YES = 3,
+ ADDRESS_FAMILY_KERNEL = 4,
_ADDRESS_FAMILY_BOOLEAN_MAX,
_ADDRESS_FAMILY_BOOLEAN_INVALID = -1,
} AddressFamilyBoolean;