chiark / gitweb /
networkd: propagate IPFoward= per-interface setting also to /proc/sys/net/ipv4/ip_forward
[elogind.git] / src / network / networkd-link.c
index 12944a03a3bca77011e2dfef8998fd3ad6d1342a..bc363f95b0084bd2ff549918e5abafbf334b38c5 100644 (file)
@@ -42,7 +42,7 @@ static bool link_dhcp6_enabled(Link *link) {
         if (!link->network)
                 return false;
 
-        return IN_SET(link->network->dhcp, DHCP_SUPPORT_V6, DHCP_SUPPORT_BOTH);
+        return IN_SET(link->network->dhcp, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES);
 }
 
 static bool link_dhcp4_enabled(Link *link) {
@@ -52,7 +52,7 @@ static bool link_dhcp4_enabled(Link *link) {
         if (!link->network)
                 return false;
 
-        return IN_SET(link->network->dhcp, DHCP_SUPPORT_V4, DHCP_SUPPORT_BOTH);
+        return IN_SET(link->network->dhcp, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES);
 }
 
 static bool link_dhcp4_server_enabled(Link *link) {
@@ -88,14 +88,24 @@ static bool link_lldp_enabled(Link *link) {
         return link->network->lldp;
 }
 
-static bool link_ip_forward_enabled(Link *link) {
+static bool link_ipv4_forward_enabled(Link *link) {
         if (link->flags & IFF_LOOPBACK)
                 return false;
 
         if (!link->network)
                 return false;
 
-        return link->network->ip_forward;
+        return IN_SET(link->network->ip_forward, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES);
+}
+
+static bool link_ipv6_forward_enabled(Link *link) {
+        if (link->flags & IFF_LOOPBACK)
+                return false;
+
+        if (!link->network)
+                return false;
+
+        return IN_SET(link->network->ip_forward, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES);
 }
 
 #define FLAG_STRING(string, flag, old, new) \
@@ -1225,14 +1235,52 @@ static int link_enter_join_netdev(Link *link) {
         return 0;
 }
 
-static int link_set_ip_forward(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 = strappenda("/proc/sys/net/ipv4/conf/", link->ifname, "/forwarding");
-        r = write_string_file_no_create(p, link_ip_forward_enabled(link) ? "1" : "0");
+        r = write_string_file_no_create(p, one_zero(b));
         if (r < 0)
-                log_link_warning_errno(link, r, "Cannot configure IP forwarding for interface: %m");
+                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;
+}
+
+static int link_set_ipv6_forward(Link *link) {
+        const char *p = NULL;
+        int r;
+
+        p = strappenda("/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)
+                log_link_warning_errno(link, r, "Cannot configure IPv6 forwarding for interface: %m");
 
         return 0;
 }
@@ -1248,7 +1296,11 @@ static int link_configure(Link *link) {
         if (r < 0)
                 return r;
 
-        r = link_set_ip_forward(link);
+        r = link_set_ipv4_forward(link);
+        if (r < 0)
+                return r;
+
+        r = link_set_ipv6_forward(link);
         if (r < 0)
                 return r;
 
@@ -1331,7 +1383,7 @@ static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
                 if (network->ipv4ll)
                         log_link_debug(link, "ignoring IPv4LL for loopback link");
 
-                if (network->dhcp != DHCP_SUPPORT_NONE)
+                if (network->dhcp != ADDRESS_FAMILY_NO)
                         log_link_debug(link, "ignoring DHCP clients for loopback link");
 
                 if (network->dhcp_server)