|
11 | 11 | #include "string-table.h" |
12 | 12 | #include "sysctl-util.h" |
13 | 13 |
|
| 14 | +#define STABLE_SECRET_APP_ID_1 SD_ID128_MAKE(aa,05,1d,94,43,68,45,07,b9,73,f1,e8,e4,b7,34,52) |
| 15 | +#define STABLE_SECRET_APP_ID_2 SD_ID128_MAKE(52,c4,40,a0,9f,2f,48,58,a9,3a,f6,29,25,ba,7a,7d) |
| 16 | + |
14 | 17 | static int link_update_ipv6_sysctl(Link *link) { |
15 | 18 | assert(link); |
16 | 19 |
|
@@ -211,6 +214,48 @@ int link_set_ipv6_mtu(Link *link) { |
211 | 214 | return sysctl_write_ip_property_uint32(AF_INET6, link->ifname, "mtu", mtu); |
212 | 215 | } |
213 | 216 |
|
| 217 | +static int link_set_ipv6ll_stable_secret(Link *link) { |
| 218 | + _cleanup_free_ char *str = NULL; |
| 219 | + struct in6_addr a; |
| 220 | + int r; |
| 221 | + |
| 222 | + assert(link); |
| 223 | + assert(link->network); |
| 224 | + |
| 225 | + if (link->network->ipv6ll_address_gen_mode != IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY) |
| 226 | + return 0; |
| 227 | + |
| 228 | + if (in6_addr_is_set(&link->network->ipv6ll_stable_secret)) |
| 229 | + a = link->network->ipv6ll_stable_secret; |
| 230 | + else { |
| 231 | + sd_id128_t key; |
| 232 | + le64_t v; |
| 233 | + |
| 234 | + /* Generate a stable secret address from machine-ID and the interface name. */ |
| 235 | + |
| 236 | + r = sd_id128_get_machine_app_specific(STABLE_SECRET_APP_ID_1, &key); |
| 237 | + if (r < 0) |
| 238 | + return log_link_debug_errno(link, r, "Failed to generate key: %m"); |
| 239 | + |
| 240 | + v = htole64(siphash24_string(link->ifname, key.bytes)); |
| 241 | + memcpy(a.s6_addr, &v, sizeof(v)); |
| 242 | + |
| 243 | + r = sd_id128_get_machine_app_specific(STABLE_SECRET_APP_ID_2, &key); |
| 244 | + if (r < 0) |
| 245 | + return log_link_debug_errno(link, r, "Failed to generate key: %m"); |
| 246 | + |
| 247 | + v = htole64(siphash24_string(link->ifname, key.bytes)); |
| 248 | + assert_cc(sizeof(v) * 2 == sizeof(a.s6_addr)); |
| 249 | + memcpy(a.s6_addr + sizeof(v), &v, sizeof(v)); |
| 250 | + } |
| 251 | + |
| 252 | + r = in6_addr_to_string(&a, &str); |
| 253 | + if (r < 0) |
| 254 | + return r; |
| 255 | + |
| 256 | + return sysctl_write_ip_property(AF_INET6, link->ifname, "stable_secret", str); |
| 257 | +} |
| 258 | + |
214 | 259 | static int link_set_ipv4_accept_local(Link *link) { |
215 | 260 | assert(link); |
216 | 261 |
|
@@ -282,6 +327,10 @@ int link_set_sysctl(Link *link) { |
282 | 327 | if (r < 0) |
283 | 328 | log_link_warning_errno(link, r, "Cannot set IPv6 MTU, ignoring: %m"); |
284 | 329 |
|
| 330 | + r = link_set_ipv6ll_stable_secret(link); |
| 331 | + if (r < 0) |
| 332 | + log_link_warning_errno(link, r, "Cannot set stable secret address for IPv6 link local address: %m"); |
| 333 | + |
285 | 334 | r = link_set_ipv4_accept_local(link); |
286 | 335 | if (r < 0) |
287 | 336 | log_link_warning_errno(link, r, "Cannot set IPv4 accept_local flag for interface, ignoring: %m"); |
|
0 commit comments