diff options
author | Susant Sahani <ssahani@users.noreply.github.com> | 2016-04-21 06:04:13 +0530 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2016-04-20 20:34:13 -0400 |
commit | 439689c6ec48faba67565562d75701d5736567e7 (patch) | |
tree | 7970f3f89b0a1331b53917f5869e41fefc9b0ef9 /src/network/networkd-link.c | |
parent | f15ab461ec10cb0164b9e6110957012d052415ea (diff) |
networkd: bump MTU to 1280 for interfaces which have IPv6 enabled (#3077)
IPv6 protocol requires a minimum MTU of 1280 bytes on the interface.
This fixes #3046.
Introduce helper link_ipv6_enabled() to figure out whether IPV6 is enabled.
Introduce network_has_static_ipv6_addresses() to find out if any static
ipv6 address configured.
If IPv6 is not configured on any interface that is SLAAC, DHCPv6 and static
IPv6 addresses not configured, then IPv6 will be automatically disabled for that
interface, that is we write "1" to /proc/sys/net/ipv6/conf//disable_ipv6.
Diffstat (limited to 'src/network/networkd-link.c')
-rw-r--r-- | src/network/networkd-link.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 9059a68fe3..0fb3aa6c43 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -99,6 +99,15 @@ static bool link_ipv6ll_enabled(Link *link) { return link->network->link_local & ADDRESS_FAMILY_IPV6; } +static bool link_ipv6_enabled(Link *link) { + assert(link); + + if (!socket_ipv6_is_supported()) + return false; + + return link_dhcp6_enabled(link) || link_ipv6ll_enabled(link) || network_has_static_ipv6_addresses(link->network); +} + static bool link_lldp_rx_enabled(Link *link) { assert(link); @@ -218,6 +227,31 @@ static IPv6PrivacyExtensions link_ipv6_privacy_extensions(Link *link) { return link->network->ipv6_privacy_extensions; } +static int link_enable_ipv6(Link *link) { + const char *p = NULL; + bool disabled; + int r; + + if (link->flags & IFF_LOOPBACK) + return 0; + + disabled = !link_ipv6_enabled(link); + + p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/disable_ipv6"); + + r = write_string_file(p, one_zero(disabled), WRITE_STRING_FILE_VERIFY_ON_FAILURE); + if (r < 0) + log_link_warning_errno(link, r, "Cannot %s IPv6 for interface %s: %m", disabled ? "disable" : "enable", link->ifname); + else { + if (disabled) + log_link_info(link, "IPv6 disabled for interface: %m"); + else + log_link_info(link, "IPv6 enabled for interface: %m"); + } + + return 0; +} + void link_update_operstate(Link *link) { LinkOperationalState operstate; assert(link); @@ -1510,7 +1544,21 @@ static int link_up(Link *link) { return log_link_error_errno(link, r, "Could not set MAC address: %m"); } + /* If IPv6 not configured (no static IPv6 address and neither DHCPv6 nor IPv6LL is enabled) + for this interface then disable IPv6 else enable it. */ + (void) link_enable_ipv6(link); + if (link->network->mtu) { + /* IPv6 protocol requires a minimum MTU of IPV6_MTU_MIN(1280) bytes + on the interface. Bump up MTU bytes to IPV6_MTU_MIN. */ + if (link_ipv6_enabled(link) && link->network->mtu < IPV6_MIN_MTU) { + + log_link_warning(link, "Bumping MTU to " STRINGIFY(IPV6_MIN_MTU) ", as " + "IPv6 is requested and requires a minimum MTU of " STRINGIFY(IPV6_MIN_MTU) " bytes: %m"); + + link->network->mtu = IPV6_MIN_MTU; + } + r = sd_netlink_message_append_u32(req, IFLA_MTU, link->network->mtu); if (r < 0) return log_link_error_errno(link, r, "Could not set MTU: %m"); @@ -1520,7 +1568,7 @@ static int link_up(Link *link) { if (r < 0) return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m"); - if (socket_ipv6_is_supported()) { + if (link_ipv6_enabled(link)) { /* if the kernel lacks ipv6 support setting IFF_UP fails if any ipv6 options are passed */ r = sd_netlink_message_open_container(req, AF_INET6); if (r < 0) |