From 1f0d9695125bf8e66d0e53e37d454755a84899bb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 6 Jul 2015 20:29:33 +0200 Subject: networkd: various fixes for the IPv6 privacy extensions support - 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 --- src/network/networkd-link.c | 22 +++++++++++++--------- src/network/networkd-network.c | 25 +++++++++++++++---------- src/network/networkd.h | 5 +++-- 3 files changed, 31 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index eb07e12773..5607cf470e 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -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; } diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index ddf03e67f9..a8e9ef909c 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -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; diff --git a/src/network/networkd.h b/src/network/networkd.h index cd5c020533..f98c640822 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -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; -- cgit v1.2.3-54-g00ecf