if (link->network->ipv6_mtu == 0)
return 0;
- return sysctl_write_ip_property_uint32(AF_INET6, link->ifname, "mtu", link->network->ipv6_mtu);
+ mtu = link->network->ipv6_mtu;
+ if (mtu > link->max_mtu) {
+ log_link_warning(link, "Reducing requested IPv6 MTU %"PRIu32" to the interface's maximum MTU %"PRIu32".",
+ mtu, link->max_mtu);
+ mtu = link->max_mtu;
+ }
+
+ return sysctl_write_ip_property_uint32(AF_INET6, link->ifname, "mtu", mtu);
}
+ static int link_set_ipv6ll_stable_secret(Link *link) {
+ _cleanup_free_ char *str = NULL;
+ struct in6_addr a;
+ int r;
+
+ assert(link);
+ assert(link->network);
+
+ if (link->network->ipv6ll_address_gen_mode != IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY)
+ return 0;
+
+ if (in6_addr_is_set(&link->network->ipv6ll_stable_secret))
+ a = link->network->ipv6ll_stable_secret;
+ else {
+ sd_id128_t key;
+ le64_t v;
+
+ /* Generate a stable secret address from machine-ID and the interface name. */
+
+ r = sd_id128_get_machine_app_specific(STABLE_SECRET_APP_ID_1, &key);
+ if (r < 0)
+ return log_link_debug_errno(link, r, "Failed to generate key: %m");
+
+ v = htole64(siphash24_string(link->ifname, key.bytes));
+ memcpy(a.s6_addr, &v, sizeof(v));
+
+ r = sd_id128_get_machine_app_specific(STABLE_SECRET_APP_ID_2, &key);
+ if (r < 0)
+ return log_link_debug_errno(link, r, "Failed to generate key: %m");
+
+ v = htole64(siphash24_string(link->ifname, key.bytes));
+ assert_cc(sizeof(v) * 2 == sizeof(a.s6_addr));
+ memcpy(a.s6_addr + sizeof(v), &v, sizeof(v));
+ }
+
+ r = in6_addr_to_string(&a, &str);
+ if (r < 0)
+ return r;
+
+ return sysctl_write_ip_property(AF_INET6, link->ifname, "stable_secret", str);
+ }
+
static int link_set_ipv4_accept_local(Link *link) {
assert(link);