]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: various fixes for the IPv6 privacy extensions support 496/head
authorLennart Poettering <lennart@poettering.net>
Mon, 6 Jul 2015 18:29:33 +0000 (20:29 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 6 Jul 2015 18:37:22 +0000 (20:37 +0200)
- Make sure that the IPv6PrivacyExtensions=yes results in
  prefer-temporary, not prefer-public.

- Introduce special enum value "kernel" to leave setting unset, similar
  how we have it for the IP forwarding settings.

- Bring the enum values in sync with the the strings we parse for them,
  to the level this makes sense (specifically, rename "disabled" to
  "no", and "prefer-temporary" to "yes").

- Make sure we really set the value to to "no" by default, the way it is
  already documented in the man page.

- Fix whitespace error.

- Make sure link_ipv6_privacy_extensions() actually returns the correct
  enum type, rather than implicitly casting it to "bool".

- properly size formatting buffer for ipv6 sysctl value

- Don't complain if /proc/sys isn't writable

- Document that the enum follows the kernel's own values (0 = off, 1 =
  prefer-public, 2 = prefer-temporary)

- Drop redundant negating of error code passed to log_syntax()

- Manpage fixes

This fixes a number of issues from PR #417

man/systemd.network.xml
src/network/networkd-link.c
src/network/networkd-network.c
src/network/networkd.h

index 85867e7f66ed3d4290b9a986432d26d25ea36e78..ff01da624947a65a6daa051989d4532d3d745100 100644 (file)
         </varlistentry>
         <varlistentry>
           <term><varname>IPv6PrivacyExtensions=</varname></term>
-          <listitem><para>Configures use of stateless temporary addresses that change over time
-          (see <ulink url="https://tools.ietf.org/html/rfc4941">RFC 4941</ulink>, Privacy Extensions for Stateless Address
-          Autoconfiguration in IPv6). A boolean or <literal>prefer-temporary</literal>. When true or <literal>prefer-public</literal>
-          enables privacy extensions, but prefer public addresses over temporary addresses.
-          <literal>prefer-temporary</literal> prefers temporary addresses over public addresses.
-          Defaults to
+          <listitem><para>Configures use of stateless temporary
+          addresses that change over time (see <ulink
+          url="https://tools.ietf.org/html/rfc4941">RFC 4941</ulink>,
+          Privacy Extensions for Stateless Address Autoconfiguration
+          in IPv6). Takes a boolean or the special values
+          <literal>prefer-public</literal> and
+          <literal>kernel</literal>. When true enables the privacy
+          extensions and prefers temporary addresses over public
+          addresses. When <literal>prefer-public</literal> enables the
+          privacy extensions, but prefers public addresses over
+          temporary addresses. When false, the privacy extensions
+          remain disabled. When <literal>kernel</literal> the kernel's
+          default setting will be left in place.  Defaults to
           <literal>no</literal>.</para></listitem>
         </varlistentry>
         <varlistentry>
index eb07e1277346e71575a2ceee2308c8e863ea4eb3..5607cf470e8a1a26a4aba8d693a10d7355235fb1 100644 (file)
@@ -116,15 +116,12 @@ static bool link_ipv6_forward_enabled(Link *link) {
         return link->network->ip_forward & ADDRESS_FAMILY_IPV6;
 }
 
-static bool link_ipv6_privacy_extensions_enabled(Link *link) {
+static IPv6PrivacyExtensions link_ipv6_privacy_extensions(Link *link) {
         if (link->flags & IFF_LOOPBACK)
-                return false;
+                return _IPV6_PRIVACY_EXTENSIONS_INVALID;
 
         if (!link->network)
-                return false;
-
-        if (link->network->ipv6_privacy_extensions == _IPV6_PRIVACY_EXTENSIONS_INVALID)
-                return false;
+                return _IPV6_PRIVACY_EXTENSIONS_INVALID;
 
         return link->network->ipv6_privacy_extensions;
 }
@@ -1540,7 +1537,8 @@ static int link_set_ipv6_forward(Link *link) {
 }
 
 static int link_set_ipv6_privacy_extensions(Link *link) {
-        char buf[2 * DECIMAL_STR_MAX(unsigned) + 1];
+        char buf[DECIMAL_STR_MAX(unsigned) + 1];
+        IPv6PrivacyExtensions s;
         const char *p = NULL;
         int r;
 
@@ -1548,15 +1546,21 @@ static int link_set_ipv6_privacy_extensions(Link *link) {
         if (!socket_ipv6_is_supported())
                 return 0;
 
-        if (!link_ipv6_privacy_extensions_enabled(link))
+        s = link_ipv6_privacy_extensions(link);
+        if (s == _IPV6_PRIVACY_EXTENSIONS_INVALID)
                 return 0;
 
         p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/use_tempaddr");
         xsprintf(buf, "%u", link->network->ipv6_privacy_extensions);
 
         r = write_string_file_no_create(p, buf);
-        if (r < 0)
+        if (r < 0) {
+                /* If the right value is set anyway, don't complain */
+                if (verify_one_line_file(p, buf) > 0)
+                        return 0;
+
                 log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface: %m");
+        }
 
         return 0;
 }
index ddf03e67f9c974dab1da7e6ba391be58f788a8dc..a8e9ef909c3eb20df33ff387ba410708250f8c5f 100644 (file)
@@ -111,7 +111,7 @@ static int network_load_one(Manager *manager, const char *filename) {
 
         network->link_local = ADDRESS_FAMILY_IPV6;
 
-        network->ipv6_privacy_extensions = _IPV6_PRIVACY_EXTENSIONS_INVALID;
+        network->ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO;
 
         r = config_parse(NULL, filename, file,
                          "Match\0"
@@ -755,9 +755,9 @@ int config_parse_address_family_boolean_with_kernel(
 }
 
 static const char* const ipv6_privacy_extensions_table[_IPV6_PRIVACY_EXTENSIONS_MAX] = {
-        [IPV6_PRIVACY_EXTENSIONS_DISABLE] = "no",
-        [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC] = "yes",
-        [IPV6_PRIVACY_EXTENSIONS_PREFER_TEMPORARY] = "prefer-temporary",
+        [IPV6_PRIVACY_EXTENSIONS_NO] = "no",
+        [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC] = "prefer-public",
+        [IPV6_PRIVACY_EXTENSIONS_YES] = "yes",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions, IPv6PrivacyExtensions);
@@ -787,16 +787,21 @@ int config_parse_ipv6_privacy_extensions(
 
         k = parse_boolean(rvalue);
         if (k > 0)
-                *ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC;
+                *ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_YES;
         else if (k == 0)
-                *ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_DISABLE;
+                *ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO;
         else {
-               IPv6PrivacyExtensions s;
+                IPv6PrivacyExtensions s;
 
                 s = ipv6_privacy_extensions_from_string(rvalue);
-                if (s < 0){
-                        log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue);
-                        return 0;
+                if (s < 0) {
+
+                        if (streq(rvalue, "kernel"))
+                                s = _IPV6_PRIVACY_EXTENSIONS_INVALID;
+                        else {
+                                log_syntax(unit, LOG_ERR, filename, line, s, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue);
+                                return 0;
+                        }
                 }
 
                 *ipv6_privacy_extensions = s;
index cd5c020533bc86f353423ab3ca7a4dbfc945eacc..f98c640822ca02a90983443f3d1d26b7a2bd993b 100644 (file)
@@ -91,9 +91,10 @@ typedef enum DCHPClientIdentifier {
 } DCHPClientIdentifier;
 
 typedef enum IPv6PrivacyExtensions {
-        IPV6_PRIVACY_EXTENSIONS_DISABLE,
+        /* The values map to the kernel's /proc/sys/net/ipv6/conf/xxx/use_tempaddr values */
+        IPV6_PRIVACY_EXTENSIONS_NO,
         IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC,
-        IPV6_PRIVACY_EXTENSIONS_PREFER_TEMPORARY,
+        IPV6_PRIVACY_EXTENSIONS_YES, /* aka prefer-temporary */
         _IPV6_PRIVACY_EXTENSIONS_MAX,
         _IPV6_PRIVACY_EXTENSIONS_INVALID = -1,
 } IPv6PrivacyExtensions;