networkd: don't touch global forwarding setting

This reverts commit 43c6d5abac
(and a small part of 4046d8361c)

It turns out we don't actually need to set the global ip_forward setting.
The only relevant setting is the one on each interface.

What the global toggle actually does is switch forwarding on/off for all
currently present interfaces and change the default for new ones.

That means that by setting the global ip_forward we

  - Introduce a race condition, because if the interface with IPForward=yes
    is brought up after one with IPForward=no, both will have forwarding
    enabled, because the global switch turns it on for all interfaces.
    If the other interface comes up first networkd correctly sets forward=0
    and it doesn't get overridden.

  - Change the forwarding setting for interfaces that networkd is not
    configured to touch, even if the user disabled forwarding via sysctl,
    either globally or per-interface

As forwarding works fine without this, as long as all relevant interfacest
individually set IPForward=yes:  just drop it

This means that non-networkd interfaces use the global default while
networkd interfaces default to off if IPForward isn't given.
This commit is contained in:
Benedikt Morbach 2015-05-10 20:52:40 +02:00 committed by Lennart Poettering
parent 57ab2eabb8
commit 505c5f6de1
2 changed files with 2 additions and 30 deletions

View file

@ -373,9 +373,7 @@
globally turned on in the kernel, with the
<filename>net.ipv4.ip_forward</filename> and
<filename>net.ipv4.ip_forward</filename> sysctl
options. Also, if this option is enabled for at least one
interface, the global options in the kernel are also enabled
as necessary, to ensure IP forwarding can take place.</para>
options.</para>
</listitem>
</varlistentry>
<varlistentry>

View file

@ -1475,39 +1475,13 @@ static int link_enter_join_netdev(Link *link) {
static int link_set_ipv4_forward(Link *link) {
const char *p = NULL;
bool b;
int r;
b = link_ipv4_forward_enabled(link);
p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/forwarding");
r = write_string_file_no_create(p, one_zero(b));
r = write_string_file_no_create(p, one_zero(link_ipv4_forward_enabled(link)));
if (r < 0)
log_link_warning_errno(link, r, "Cannot configure IPv4 forwarding for interface %s: %m", link->ifname);
if (b) {
_cleanup_free_ char *buf = NULL;
/* If IP forwarding is turned on for this interface,
* then propagate this to the global setting. Given
* that turning this on has side-effects on other
* fields, we'll try to avoid doing this unless
* necessary, hence check the previous value
* first. Note that we never turn this option off
* again, since all interfaces we manage do not do
* forwarding anyway by default, and ownership rules
* of this control are so unclear. */
r = read_one_line_file("/proc/sys/net/ipv4/ip_forward", &buf);
if (r < 0)
log_link_warning_errno(link, r, "Cannot read /proc/sys/net/ipv4/ip_forward: %m");
else if (!streq(buf, "1")) {
r = write_string_file_no_create("/proc/sys/net/ipv4/ip_forward", "1");
if (r < 0)
log_link_warning_errno(link, r, "Cannot write /proc/sys/net/ipv4/ip_forward: %m");
}
}
return 0;
}