]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: be more defensive when writing to ipv4/ipv6 forwarding settings 495/head
authorLennart Poettering <lennart@poettering.net>
Mon, 6 Jul 2015 11:38:47 +0000 (13:38 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 6 Jul 2015 11:41:51 +0000 (13:41 +0200)
1) never bother with setting the flag for loopback devices

2) if we fail to write the flag due to EROFS (which is likely to happen
   in containers where /proc/sys is read-only) or any other error, check
   if the flag already has the right value. If so, don't complain.

Closes #469

src/basic/fileio.c
src/basic/fileio.h
src/network/networkd-link.c

index ff6b1a7ed776db2c6b53a41b09fec1ed43466396..00fb6f8b5cce1b6f75190bcb992383a7fdc563a8 100644 (file)
@@ -134,6 +134,17 @@ int read_one_line_file(const char *fn, char **line) {
         return 0;
 }
 
+int verify_one_line_file(const char *fn, const char *line) {
+        _cleanup_free_ char *value = NULL;
+        int r;
+
+        r = read_one_line_file(fn, &value);
+        if (r < 0)
+                return r;
+
+        return streq(value, line);
+}
+
 int read_full_stream(FILE *f, char **contents, size_t *size) {
         size_t n, l;
         _cleanup_free_ char *buf = NULL;
index 5ae51c1e28a9daa56d4fee59f25a11bf2f06922d..91d4a0d2d5034ec9610435f8fc55c0773fdf4995 100644 (file)
@@ -34,6 +34,8 @@ int read_one_line_file(const char *fn, char **line);
 int read_full_file(const char *fn, char **contents, size_t *size);
 int read_full_stream(FILE *f, char **contents, size_t *size);
 
+int verify_one_line_file(const char *fn, const char *line);
+
 int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
 int load_env_file(FILE *f, const char *fname, const char *separator, char ***l);
 int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l);
index f67a19e50b798656bcb707af3624f6b147143890..eb07e1277346e71575a2ceee2308c8e863ea4eb3 100644 (file)
@@ -1486,35 +1486,55 @@ static int link_enter_join_netdev(Link *link) {
 }
 
 static int link_set_ipv4_forward(Link *link) {
-        const char *p = NULL;
+        const char *p = NULL, *v;
         int r;
 
+        if (link->flags & IFF_LOOPBACK)
+                return 0;
+
         if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID)
                 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)
+        v = one_zero(link_ipv4_forward_enabled(link));
+
+        r = write_string_file_no_create(p, v);
+        if (r < 0) {
+                /* If the right value is set anyway, don't complain */
+                if (verify_one_line_file(p, v) > 0)
+                        return 0;
+
                 log_link_warning_errno(link, r, "Cannot configure IPv4 forwarding for interface %s: %m", link->ifname);
+        }
 
         return 0;
 }
 
 static int link_set_ipv6_forward(Link *link) {
-        const char *p = NULL;
+        const char *p = NULL, *v = NULL;
         int r;
 
         /* Make this a NOP if IPv6 is not available */
         if (!socket_ipv6_is_supported())
                 return 0;
 
+        if (link->flags & IFF_LOOPBACK)
+                return 0;
+
         if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID)
                 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)
+        v = one_zero(link_ipv6_forward_enabled(link));
+
+        r = write_string_file_no_create(p, v);
+        if (r < 0) {
+                /* If the right value is set anyway, don't complain */
+                if (verify_one_line_file(p, v) > 0)
+                        return 0;
+
                 log_link_warning_errno(link, r, "Cannot configure IPv6 forwarding for interface: %m");
+        }
 
         return 0;
 }