diff options
-rw-r--r-- | man/systemd.network.xml | 8 | ||||
-rw-r--r-- | src/network/networkd-link.c | 35 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 1 | ||||
-rw-r--r-- | src/network/networkd-network.c | 1 | ||||
-rw-r--r-- | src/network/networkd-network.h | 1 |
5 files changed, 46 insertions, 0 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 50f3810ce0..7d081d22fe 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -432,6 +432,14 @@ </para></listitem> </varlistentry> <varlistentry> + <term><varname>IPv6HopLimit=</varname></term> + <listitem><para>Configures IPv6 Hop Limit. For each router that + forwards the packet, the hop limit is decremented by 1. When the + hop limit field reaches zero, the packet is discarded. + Defaults to unset. + </para></listitem> + </varlistentry> + <varlistentry> <term><varname>Bridge=</varname></term> <listitem> <para>The name of the bridge to add the link to.</para> diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 46979ffa12..13d2fc6d0d 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1952,6 +1952,37 @@ static int link_set_ipv6_dad_transmits(Link *link) { return 0; } +static int link_set_ipv6_hop_limit(Link *link) { + char buf[DECIMAL_STR_MAX(unsigned) + 1]; + const char *p = 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->ipv6_hop_limit < 0) + return 0; + + p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/hop_limit"); + + xsprintf(buf, "%u", link->network->ipv6_hop_limit); + + r = write_string_file(p, buf, 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 set IPv6 hop limit for interface: %m"); + } + + return 0; +} + static int link_configure(Link *link) { int r; @@ -1983,6 +2014,10 @@ static int link_configure(Link *link) { if (r < 0) return r; + r = link_set_ipv6_hop_limit(link); + if (r < 0) + return r; + if (link_ipv4ll_enabled(link)) { r = ipv4ll_configure(link); if (r < 0) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index cc01dc24c9..de2c66d153 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -52,6 +52,7 @@ Network.IPMasquerade, config_parse_bool, Network.IPv6PrivacyExtensions, config_parse_ipv6_privacy_extensions, 0, offsetof(Network, ipv6_privacy_extensions) Network.IPv6AcceptRouterAdvertisements, config_parse_tristate, 0, offsetof(Network, ipv6_accept_ra) Network.IPv6DuplicateAddressDetection, config_parse_int, 0, offsetof(Network, ipv6_dad_transmits) +Network.IPv6HopLimit, config_parse_int, 0, offsetof(Network, ipv6_hop_limit) Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier) Address.Address, config_parse_address, 0, 0 Address.Peer, config_parse_address, 0, 0 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 0188cb6fe5..29723a852f 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -127,6 +127,7 @@ static int network_load_one(Manager *manager, const char *filename) { network->ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO; network->ipv6_accept_ra = -1; network->ipv6_dad_transmits = -1; + network->ipv6_hop_limit = -1; r = config_parse(NULL, filename, file, "Match\0" diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index c2872908b5..a27c67eea5 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -122,6 +122,7 @@ struct Network { int ipv6_accept_ra; int ipv6_dad_transmits; + int ipv6_hop_limit; union in_addr_union ipv6_token; IPv6PrivacyExtensions ipv6_privacy_extensions; |