]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-address.c
network: make address_free() return NULL
[thirdparty/systemd.git] / src / network / networkd-address.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
f579559b
TG
2
3#include <net/if.h>
4
b5efdb8a 5#include "alloc-util.h"
f579559b 6#include "conf-parser.h"
12c2884c 7#include "firewall-util.h"
0a970718 8#include "memory-util.h"
081aea25 9#include "missing_network.h"
fc2f9534 10#include "netlink-util.h"
6bedfcbb 11#include "networkd-address.h"
23f53b99 12#include "networkd-manager.h"
50550722 13#include "networkd-ndisc.h"
6bedfcbb 14#include "parse-util.h"
3ac8e543 15#include "set.h"
d31645ad 16#include "socket-util.h"
07630cea 17#include "string-util.h"
51517f9e 18#include "strv.h"
3ac8e543 19#include "utf8.h"
f579559b 20
1b566071 21#define ADDRESSES_PER_LINK_MAX 2048U
8c34b963
LP
22#define STATIC_ADDRESSES_PER_NETWORK_MAX 1024U
23
5ead5352
SS
24int generate_ipv6_eui_64_address(Link *link, struct in6_addr *ret) {
25 assert(link);
26 assert(ret);
27
28 /* see RFC4291 section 2.5.1 */
29 ret->s6_addr[8] = link->mac.ether_addr_octet[0];
30 ret->s6_addr[8] ^= 1 << 1;
31 ret->s6_addr[9] = link->mac.ether_addr_octet[1];
32 ret->s6_addr[10] = link->mac.ether_addr_octet[2];
33 ret->s6_addr[11] = 0xff;
34 ret->s6_addr[12] = 0xfe;
35 ret->s6_addr[13] = link->mac.ether_addr_octet[3];
36 ret->s6_addr[14] = link->mac.ether_addr_octet[4];
37 ret->s6_addr[15] = link->mac.ether_addr_octet[5];
38
39 return 0;
40}
41
f0213e37 42int address_new(Address **ret) {
8e766630 43 _cleanup_(address_freep) Address *address = NULL;
f0213e37 44
17f9c355 45 address = new(Address, 1);
f0213e37
TG
46 if (!address)
47 return -ENOMEM;
aba496a5 48
17f9c355
YW
49 *address = (Address) {
50 .family = AF_UNSPEC,
51 .scope = RT_SCOPE_UNIVERSE,
52 .cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME,
53 .cinfo.ifa_valid = CACHE_INFO_INFINITY_LIFE_TIME,
051e77ca 54 .duplicate_address_detection = ADDRESS_FAMILY_IPV6,
de697db0 55 .prefix_route = true,
17f9c355 56 };
f0213e37 57
1cc6c93a 58 *ret = TAKE_PTR(address);
f0213e37
TG
59
60 return 0;
aba496a5
UTL
61}
62
9560e5b3 63static int address_new_static(Network *network, const char *filename, unsigned section_line, Address **ret) {
8e766630
LP
64 _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
65 _cleanup_(address_freep) Address *address = NULL;
f0213e37 66 int r;
f579559b 67
8c34b963
LP
68 assert(network);
69 assert(ret);
48317c39 70 assert(!!filename == (section_line > 0));
8c34b963 71
48317c39 72 if (filename) {
f4859fc7
SS
73 r = network_config_section_new(filename, section_line, &n);
74 if (r < 0)
75 return r;
76
77 address = hashmap_get(network->addresses_by_section, n);
6ae115c1 78 if (address) {
1cc6c93a 79 *ret = TAKE_PTR(address);
6ae115c1
TG
80
81 return 0;
82 }
83 }
84
8c34b963
LP
85 if (network->n_static_addresses >= STATIC_ADDRESSES_PER_NETWORK_MAX)
86 return -E2BIG;
87
f0213e37
TG
88 r = address_new(&address);
89 if (r < 0)
90 return r;
801bd9e8 91
0f7f2769
YW
92 address->network = network;
93 LIST_APPEND(addresses, network->static_addresses, address);
94 network->n_static_addresses++;
95
48317c39 96 if (filename) {
1cc6c93a 97 address->section = TAKE_PTR(n);
fcc48287 98
3e570042
YW
99 r = hashmap_ensure_allocated(&network->addresses_by_section, &network_config_hash_ops);
100 if (r < 0)
101 return r;
102
f7fe70ea
SS
103 r = hashmap_put(network->addresses_by_section, address->section, address);
104 if (r < 0)
105 return r;
6ae115c1
TG
106 }
107
1cc6c93a 108 *ret = TAKE_PTR(address);
f579559b
TG
109
110 return 0;
111}
112
7818f858 113Address *address_free(Address *address) {
f579559b 114 if (!address)
7818f858 115 return NULL;
f579559b 116
f048a16b 117 if (address->network) {
3d3d4255 118 LIST_REMOVE(addresses, address->network->static_addresses, address);
8c34b963
LP
119 assert(address->network->n_static_addresses > 0);
120 address->network->n_static_addresses--;
f579559b 121
de4224aa 122 if (address->section)
f4859fc7 123 hashmap_remove(address->network->addresses_by_section, address->section);
f048a16b 124 }
6ae115c1 125
051e77ca 126 if (address->link && !address->acd) {
50550722 127 NDiscAddress *n;
50550722 128
cf1d700d 129 set_remove(address->link->addresses, address);
adda1ed9 130 set_remove(address->link->addresses_foreign, address);
e5526518 131 set_remove(address->link->static_addresses, address);
6e537f62
YW
132 if (address->link->dhcp_address == address)
133 address->link->dhcp_address = NULL;
134 if (address->link->dhcp_address_old == address)
135 address->link->dhcp_address_old = NULL;
1633c457
YW
136 set_remove(address->link->dhcp6_addresses, address);
137 set_remove(address->link->dhcp6_addresses_old, address);
138 set_remove(address->link->dhcp6_pd_addresses, address);
139 set_remove(address->link->dhcp6_pd_addresses_old, address);
90e74a66 140 SET_FOREACH(n, address->link->ndisc_addresses)
50550722
YW
141 if (n->address == address)
142 free(set_remove(address->link->ndisc_addresses, n));
f150100a
SS
143
144 if (in_addr_equal(AF_INET6, &address->in_addr, (const union in_addr_union *) &address->link->ipv6ll_address))
145 memzero(&address->link->ipv6ll_address, sizeof(struct in6_addr));
adda1ed9 146 }
cf1d700d 147
051e77ca
SS
148 sd_ipv4acd_unref(address->acd);
149
de4224aa
YW
150 network_config_section_free(address->section);
151 free(address->label);
7818f858 152 return mfree(address);
f579559b
TG
153}
154
24be9181
ZJS
155static uint32_t address_prefix(const Address *a) {
156 assert(a);
157
158 /* make sure we don't try to shift by 32.
159 * See ISO/IEC 9899:TC3 § 6.5.7.3. */
160 if (a->prefixlen == 0)
161 return 0;
162
163 if (a->in_addr_peer.in.s_addr != 0)
164 return be32toh(a->in_addr_peer.in.s_addr) >> (32 - a->prefixlen);
165 else
166 return be32toh(a->in_addr.in.s_addr) >> (32 - a->prefixlen);
167}
168
99a28784 169void address_hash_func(const Address *a, struct siphash *state) {
3ac8e543
TG
170 assert(a);
171
172 siphash24_compress(&a->family, sizeof(a->family), state);
173
174 switch (a->family) {
175 case AF_INET:
176 siphash24_compress(&a->prefixlen, sizeof(a->prefixlen), state);
177
178 /* peer prefix */
24be9181
ZJS
179 uint32_t prefix = address_prefix(a);
180 siphash24_compress(&prefix, sizeof(prefix), state);
3ac8e543 181
4831981d 182 _fallthrough_;
3ac8e543
TG
183 case AF_INET6:
184 /* local address */
185 siphash24_compress(&a->in_addr, FAMILY_ADDRESS_SIZE(a->family), state);
186
187 break;
188 default:
189 /* treat any other address family as AF_UNSPEC */
190 break;
191 }
192}
193
99a28784 194int address_compare_func(const Address *a1, const Address *a2) {
a0edd02e 195 int r;
3ac8e543 196
a0edd02e
FB
197 r = CMP(a1->family, a2->family);
198 if (r != 0)
199 return r;
3ac8e543
TG
200
201 switch (a1->family) {
202 /* use the same notion of equality as the kernel does */
203 case AF_INET:
a0edd02e
FB
204 r = CMP(a1->prefixlen, a2->prefixlen);
205 if (r != 0)
206 return r;
3ac8e543 207
24be9181
ZJS
208 uint32_t prefix1 = address_prefix(a1);
209 uint32_t prefix2 = address_prefix(a2);
210 r = CMP(prefix1, prefix2);
211 if (r != 0)
212 return r;
3ac8e543 213
4831981d 214 _fallthrough_;
3ac8e543
TG
215 case AF_INET6:
216 return memcmp(&a1->in_addr, &a2->in_addr, FAMILY_ADDRESS_SIZE(a1->family));
217 default:
218 /* treat any other address family as AF_UNSPEC */
219 return 0;
220 }
221}
222
8eec0b9d 223DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(address_hash_ops, Address, address_hash_func, address_compare_func, address_free);
3ac8e543
TG
224
225bool address_equal(Address *a1, Address *a2) {
226 if (a1 == a2)
227 return true;
228
229 if (!a1 || !a2)
230 return false;
231
232 return address_compare_func(a1, a2) == 0;
233}
234
91b5f997
TG
235static int address_establish(Address *address, Link *link) {
236 bool masq;
237 int r;
238
239 assert(address);
240 assert(link);
241
242 masq = link->network &&
fcf50cff
TG
243 link->network->ip_masquerade &&
244 address->family == AF_INET &&
245 address->scope < RT_SCOPE_LINK;
91b5f997
TG
246
247 /* Add firewall entry if this is requested */
248 if (address->ip_masquerade_done != masq) {
249 union in_addr_union masked = address->in_addr;
250 in_addr_mask(address->family, &masked, address->prefixlen);
251
252 r = fw_add_masquerade(masq, AF_INET, 0, &masked, address->prefixlen, NULL, NULL, 0);
253 if (r < 0)
7750b796 254 return r;
91b5f997
TG
255
256 address->ip_masquerade_done = masq;
257 }
258
259 return 0;
260}
261
adda1ed9
TG
262static int address_add_internal(Link *link, Set **addresses,
263 int family,
264 const union in_addr_union *in_addr,
265 unsigned char prefixlen,
266 Address **ret) {
8e766630 267 _cleanup_(address_freep) Address *address = NULL;
cf1d700d
TG
268 int r;
269
270 assert(link);
adda1ed9 271 assert(addresses);
054f0db4 272 assert(in_addr);
054f0db4
TG
273
274 r = address_new(&address);
275 if (r < 0)
276 return r;
277
278 address->family = family;
279 address->in_addr = *in_addr;
280 address->prefixlen = prefixlen;
63bbe5c7
TG
281 /* Consider address tentative until we get the real flags from the kernel */
282 address->flags = IFA_F_TENTATIVE;
cf1d700d 283
de7fef4b 284 r = set_ensure_put(addresses, &address_hash_ops, address);
cf1d700d
TG
285 if (r < 0)
286 return r;
75a302b5
YW
287 if (r == 0)
288 return -EEXIST;
cf1d700d
TG
289
290 address->link = link;
291
adda1ed9
TG
292 if (ret)
293 *ret = address;
de7fef4b 294 TAKE_PTR(address);
cf1d700d
TG
295 return 0;
296}
297
adda1ed9
TG
298int address_add_foreign(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) {
299 return address_add_internal(link, &link->addresses_foreign, family, in_addr, prefixlen, ret);
300}
301
c4a03a56 302int address_add(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) {
cab974b0 303 Address *address;
e7780c8d
TG
304 int r;
305
cab974b0
TG
306 r = address_get(link, family, in_addr, prefixlen, &address);
307 if (r == -ENOENT) {
308 /* Address does not exist, create a new one */
309 r = address_add_internal(link, &link->addresses, family, in_addr, prefixlen, &address);
310 if (r < 0)
311 return r;
312 } else if (r == 0) {
313 /* Take over a foreign address */
de7fef4b 314 r = set_ensure_put(&link->addresses, &address_hash_ops, address);
cab974b0
TG
315 if (r < 0)
316 return r;
317
318 set_remove(link->addresses_foreign, address);
319 } else if (r == 1) {
320 /* Already exists, do nothing */
321 ;
322 } else
e7780c8d
TG
323 return r;
324
cab974b0
TG
325 if (ret)
326 *ret = address;
e7780c8d
TG
327
328 return 0;
adda1ed9
TG
329}
330
fcf50cff 331static int address_release(Address *address) {
5a8bcb67
LP
332 int r;
333
334 assert(address);
fcf50cff 335 assert(address->link);
5a8bcb67 336
91b5f997
TG
337 /* Remove masquerading firewall entry if it was added */
338 if (address->ip_masquerade_done) {
5a8bcb67
LP
339 union in_addr_union masked = address->in_addr;
340 in_addr_mask(address->family, &masked, address->prefixlen);
341
91b5f997 342 r = fw_add_masquerade(false, AF_INET, 0, &masked, address->prefixlen, NULL, NULL, 0);
5a8bcb67 343 if (r < 0)
7750b796 344 return r;
5a8bcb67 345
91b5f997 346 address->ip_masquerade_done = false;
5a8bcb67
LP
347 }
348
349 return 0;
350}
351
889b550f
LP
352int address_update(
353 Address *address,
354 unsigned char flags,
355 unsigned char scope,
356 const struct ifa_cacheinfo *cinfo) {
357
36c32f61 358 bool ready;
e7ab854c 359 int r;
36c32f61
TG
360
361 assert(address);
ea121d8f 362 assert(address->link);
36c32f61
TG
363 assert(cinfo);
364
365 ready = address_is_ready(address);
366
367 address->flags = flags;
368 address->scope = scope;
369 address->cinfo = *cinfo;
370
ea121d8f
YW
371 if (IN_SET(address->link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
372 return 0;
373
959f65d3 374 link_update_operstate(address->link, true);
c8f7123e 375 link_check_ready(address->link);
7209086d 376
97f00074
YW
377 if (!ready && address_is_ready(address)) {
378 if (address->callback) {
379 r = address->callback(address);
380 if (r < 0)
381 return r;
382 }
7209086d 383
97f00074
YW
384 if (address->family == AF_INET6 &&
385 in_addr_is_link_local(AF_INET6, &address->in_addr) > 0 &&
386 IN6_IS_ADDR_UNSPECIFIED(&address->link->ipv6ll_address) > 0) {
387
388 r = link_ipv6ll_gained(address->link, &address->in_addr.in6);
389 if (r < 0)
390 return r;
391 }
a3a019e1 392 }
36c32f61
TG
393
394 return 0;
395}
396
91b5f997 397int address_drop(Address *address) {
8012cd39
TG
398 Link *link;
399 bool ready;
7750b796 400 int r;
8012cd39 401
5a8bcb67 402 assert(address);
91b5f997 403
8012cd39
TG
404 ready = address_is_ready(address);
405 link = address->link;
406
7750b796
YW
407 r = address_release(address);
408 if (r < 0)
409 log_link_warning_errno(link, r, "Failed to disable IP masquerading, ignoring: %m");
410
91b5f997
TG
411 address_free(address);
412
959f65d3 413 link_update_operstate(link, true);
84de38c5 414
8012cd39
TG
415 if (link && !ready)
416 link_check_ready(link);
417
91b5f997
TG
418 return 0;
419}
420
1b566071
LP
421int address_get(Link *link,
422 int family,
423 const union in_addr_union *in_addr,
424 unsigned char prefixlen,
425 Address **ret) {
426
427 Address address, *existing;
91b5f997 428
5a8bcb67 429 assert(link);
91b5f997 430 assert(in_addr);
5a8bcb67 431
1b566071
LP
432 address = (Address) {
433 .family = family,
434 .in_addr = *in_addr,
435 .prefixlen = prefixlen,
436 };
5a8bcb67 437
91b5f997 438 existing = set_get(link->addresses, &address);
cab974b0 439 if (existing) {
1b566071
LP
440 if (ret)
441 *ret = existing;
cab974b0 442 return 1;
adda1ed9 443 }
5a8bcb67 444
1b566071
LP
445 existing = set_get(link->addresses_foreign, &address);
446 if (existing) {
447 if (ret)
448 *ret = existing;
449 return 0;
450 }
5a8bcb67 451
1b566071 452 return -ENOENT;
5a8bcb67
LP
453}
454
5eec0a08
YW
455static bool address_exists_internal(Set *addresses, int family, const union in_addr_union *in_addr) {
456 Address *address;
5eec0a08 457
90e74a66 458 SET_FOREACH(address, addresses) {
5eec0a08
YW
459 if (address->family != family)
460 continue;
461 if (in_addr_equal(address->family, &address->in_addr, in_addr))
462 return true;
463 }
464
465 return false;
466}
467
468bool address_exists(Link *link, int family, const union in_addr_union *in_addr) {
469 assert(link);
470 assert(IN_SET(family, AF_INET, AF_INET6));
471 assert(in_addr);
472
473 if (address_exists_internal(link->addresses, family, in_addr))
474 return true;
475 if (address_exists_internal(link->addresses_foreign, family, in_addr))
476 return true;
477 return false;
478}
479
302a796f 480static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
63ae0569
YW
481 int r;
482
483 assert(m);
484 assert(link);
485 assert(link->ifname);
486
487 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
488 return 1;
489
490 r = sd_netlink_message_get_errno(m);
491 if (r < 0 && r != -EADDRNOTAVAIL)
5ecb131d 492 log_link_message_warning_errno(link, m, r, "Could not drop address");
fb282d4e 493 else if (r >= 0)
93b0b88c 494 (void) manager_rtnl_process_address(rtnl, m, link->manager);
63ae0569
YW
495
496 return 1;
497}
498
483d099e
ZJS
499int address_remove(
500 Address *address,
501 Link *link,
302a796f 502 link_netlink_message_handler_t callback) {
483d099e 503
4afd3348 504 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
407fe036
TG
505 int r;
506
507 assert(address);
4c701096 508 assert(IN_SET(address->family, AF_INET, AF_INET6));
407fe036
TG
509 assert(link);
510 assert(link->ifindex > 0);
511 assert(link->manager);
512 assert(link->manager->rtnl);
513
30226d27 514 if (DEBUG_LOGGING) {
7750b796
YW
515 _cleanup_free_ char *b = NULL;
516
517 (void) in_addr_to_string(address->family, &address->in_addr, &b);
518 log_link_debug(link, "Removing address %s", strna(b));
30226d27
TJ
519 }
520
151b9b96
LP
521 r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_DELADDR,
522 link->ifindex, address->family);
eb56eb9b 523 if (r < 0)
7750b796 524 return log_link_error_errno(link, r, "Could not allocate RTM_DELADDR message: %m");
407fe036 525
5a723174 526 r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
eb56eb9b 527 if (r < 0)
7750b796 528 return log_link_error_errno(link, r, "Could not set prefixlen: %m");
5a723174 529
43409486 530 r = netlink_message_append_in_addr_union(req, IFA_LOCAL, address->family, &address->in_addr);
eb56eb9b 531 if (r < 0)
7750b796 532 return log_link_error_errno(link, r, "Could not append IFA_LOCAL attribute: %m");
407fe036 533
302a796f
YW
534 r = netlink_call_async(link->manager->rtnl, NULL, req,
535 callback ?: address_remove_handler,
536 link_netlink_destroy_callback, link);
eb56eb9b 537 if (r < 0)
7750b796 538 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
407fe036 539
563c69c6
TG
540 link_ref(link);
541
407fe036
TG
542 return 0;
543}
544
f8f2f880
YW
545static bool link_is_static_address_configured(Link *link, Address *address) {
546 Address *net_address;
547
548 assert(link);
549 assert(address);
550
551 if (!link->network)
552 return false;
553
554 LIST_FOREACH(addresses, net_address, link->network->static_addresses)
555 if (address_equal(net_address, address))
556 return true;
557 else if (address->family == AF_INET6 && net_address->family == AF_INET6 &&
558 in_addr_equal(AF_INET6, &address->in_addr, &net_address->in_addr_peer) > 0)
559 return true;
560
561 return false;
562}
563
564static bool link_address_is_dynamic(Link *link, Address *address) {
565 Route *route;
566
567 assert(link);
568 assert(address);
569
570 if (address->cinfo.ifa_prefered != CACHE_INFO_INFINITY_LIFE_TIME)
571 return true;
572
573 /* Even when the address is leased from a DHCP server, networkd assign the address
574 * without lifetime when KeepConfiguration=dhcp. So, let's check that we have
575 * corresponding routes with RTPROT_DHCP. */
576 SET_FOREACH(route, link->routes_foreign) {
577 if (route->protocol != RTPROT_DHCP)
578 continue;
579
580 if (address->family != route->family)
581 continue;
582
583 if (in_addr_equal(address->family, &address->in_addr, &route->prefsrc))
584 return true;
585 }
586
587 return false;
588}
589
590int link_drop_foreign_addresses(Link *link) {
591 Address *address;
592 int k, r = 0;
593
594 assert(link);
595
596 SET_FOREACH(address, link->addresses_foreign) {
597 /* we consider IPv6LL addresses to be managed by the kernel */
598 if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1 && link_ipv6ll_enabled(link))
599 continue;
600
601 if (link_address_is_dynamic(link, address)) {
602 if (link->network && FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
603 continue;
604 } else if (link->network && FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
605 continue;
606
607 if (link_is_static_address_configured(link, address)) {
608 k = address_add(link, address->family, &address->in_addr, address->prefixlen, NULL);
609 if (k < 0) {
610 log_link_error_errno(link, k, "Failed to add address: %m");
611 if (r >= 0)
612 r = k;
613 }
614 } else {
615 k = address_remove(address, link, NULL);
616 if (k < 0 && r >= 0)
617 r = k;
618 }
619 }
620
621 return r;
622}
623
d7fbb9f5
YW
624static int remove_static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
625 int r;
626
627 assert(m);
628 assert(link);
629 assert(link->ifname);
630 assert(link->address_remove_messages > 0);
631
632 link->address_remove_messages--;
633
634 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
635 return 1;
636
637 r = sd_netlink_message_get_errno(m);
638 if (r < 0 && r != -EADDRNOTAVAIL)
639 log_link_message_warning_errno(link, m, r, "Could not drop address");
640 else if (r >= 0)
641 (void) manager_rtnl_process_address(rtnl, m, link->manager);
642
643 if (link->address_remove_messages == 0 && link->request_static_addresses) {
644 link_set_state(link, LINK_STATE_CONFIGURING);
645 r = link_set_addresses(link);
646 if (r < 0)
647 link_enter_failed(link);
648 }
649
650 return 1;
651}
652
653int link_drop_addresses(Link *link) {
654 Address *address, *pool_address;
655 int k, r = 0;
656
657 assert(link);
658
659 SET_FOREACH(address, link->addresses) {
660 /* we consider IPv6LL addresses to be managed by the kernel */
661 if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1 && link_ipv6ll_enabled(link))
662 continue;
663
664 k = address_remove(address, link, remove_static_address_handler);
665 if (k < 0 && r >= 0) {
666 r = k;
667 continue;
668 }
669
670 link->address_remove_messages++;
671
672 /* If this address came from an address pool, clean up the pool */
673 LIST_FOREACH(addresses, pool_address, link->pool_addresses)
674 if (address_equal(address, pool_address)) {
675 LIST_REMOVE(addresses, link->pool_addresses, pool_address);
676 address_free(pool_address);
677 break;
678 }
679 }
680
681 return r;
682}
683
11bf3cce 684static int address_acquire(Link *link, Address *original, Address **ret) {
67a46833 685 union in_addr_union in_addr = IN_ADDR_NULL;
11bf3cce 686 struct in_addr broadcast = {};
8e766630 687 _cleanup_(address_freep) Address *na = NULL;
11bf3cce
LP
688 int r;
689
690 assert(link);
691 assert(original);
692 assert(ret);
693
694 /* Something useful was configured? just use it */
7e43ebfb
YW
695 r = in_addr_is_null(original->family, &original->in_addr);
696 if (r <= 0)
697 return r;
11bf3cce
LP
698
699 /* The address is configured to be 0.0.0.0 or [::] by the user?
700 * Then let's acquire something more useful from the pool. */
701 r = manager_address_pool_acquire(link->manager, original->family, original->prefixlen, &in_addr);
6a7a4e4d 702 if (r < 0)
7750b796
YW
703 return r;
704 if (r == 0)
11bf3cce 705 return -EBUSY;
11bf3cce
LP
706
707 if (original->family == AF_INET) {
d076c6f9 708 /* Pick first address in range for ourselves ... */
11bf3cce
LP
709 in_addr.in.s_addr = in_addr.in.s_addr | htobe32(1);
710
711 /* .. and use last as broadcast address */
e87e2b78
SS
712 if (original->prefixlen > 30)
713 broadcast.s_addr = 0;
714 else
715 broadcast.s_addr = in_addr.in.s_addr | htobe32(0xFFFFFFFFUL >> original->prefixlen);
11bf3cce
LP
716 } else if (original->family == AF_INET6)
717 in_addr.in6.s6_addr[15] |= 1;
718
f0213e37 719 r = address_new(&na);
11bf3cce
LP
720 if (r < 0)
721 return r;
722
723 na->family = original->family;
724 na->prefixlen = original->prefixlen;
725 na->scope = original->scope;
726 na->cinfo = original->cinfo;
727
728 if (original->label) {
729 na->label = strdup(original->label);
0099bc15 730 if (!na->label)
11bf3cce 731 return -ENOMEM;
11bf3cce
LP
732 }
733
734 na->broadcast = broadcast;
735 na->in_addr = in_addr;
736
737 LIST_PREPEND(addresses, link->pool_addresses, na);
738
1cc6c93a 739 *ret = TAKE_PTR(na);
0099bc15 740
11bf3cce
LP
741 return 0;
742}
743
1b566071
LP
744int address_configure(
745 Address *address,
746 Link *link,
302a796f 747 link_netlink_message_handler_t callback,
80b0e860
YW
748 bool update,
749 Address **ret) {
1b566071 750
4afd3348 751 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
80b0e860 752 Address *a;
f579559b
TG
753 int r;
754
c166a070 755 assert(address);
4c701096 756 assert(IN_SET(address->family, AF_INET, AF_INET6));
c166a070
TG
757 assert(link);
758 assert(link->ifindex > 0);
f882c247 759 assert(link->manager);
c166a070 760 assert(link->manager->rtnl);
bd1175bc 761 assert(callback);
f882c247 762
1b566071
LP
763 /* If this is a new address, then refuse adding more than the limit */
764 if (address_get(link, address->family, &address->in_addr, address->prefixlen, NULL) <= 0 &&
765 set_size(link->addresses) >= ADDRESSES_PER_LINK_MAX)
7750b796
YW
766 return log_link_error_errno(link, SYNTHETIC_ERRNO(E2BIG),
767 "Too many addresses are configured, refusing: %m");
1b566071 768
11bf3cce
LP
769 r = address_acquire(link, address, &address);
770 if (r < 0)
7750b796 771 return log_link_error_errno(link, r, "Failed to acquire an address from pool: %m");
11bf3cce 772
3606ca65
YW
773 if (DEBUG_LOGGING) {
774 _cleanup_free_ char *str = NULL;
775
776 (void) in_addr_to_string(address->family, &address->in_addr, &str);
777 log_link_debug(link, "%s address: %s", update ? "Updating" : "Configuring", strna(str));
778 }
779
66669078
TG
780 if (update)
781 r = sd_rtnl_message_new_addr_update(link->manager->rtnl, &req,
782 link->ifindex, address->family);
783 else
784 r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_NEWADDR,
785 link->ifindex, address->family);
eb56eb9b 786 if (r < 0)
7750b796 787 return log_link_error_errno(link, r, "Could not allocate RTM_NEWADDR message: %m");
f579559b 788
5a723174 789 r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
eb56eb9b 790 if (r < 0)
7750b796 791 return log_link_error_errno(link, r, "Could not set prefixlen: %m");
5a723174 792
851c9f82
PF
793 address->flags |= IFA_F_PERMANENT;
794
e63be084
SS
795 if (address->home_address)
796 address->flags |= IFA_F_HOMEADDRESS;
797
051e77ca 798 if (!FLAGS_SET(address->duplicate_address_detection, ADDRESS_FAMILY_IPV6))
e63be084
SS
799 address->flags |= IFA_F_NODAD;
800
801 if (address->manage_temporary_address)
802 address->flags |= IFA_F_MANAGETEMPADDR;
803
de697db0 804 if (!address->prefix_route)
e63be084
SS
805 address->flags |= IFA_F_NOPREFIXROUTE;
806
807 if (address->autojoin)
808 address->flags |= IFA_F_MCAUTOJOIN;
809
851c9f82 810 r = sd_rtnl_message_addr_set_flags(req, (address->flags & 0xff));
eb56eb9b 811 if (r < 0)
7750b796 812 return log_link_error_errno(link, r, "Could not set flags: %m");
5a723174 813
851c9f82 814 if (address->flags & ~0xff) {
1c4baffc 815 r = sd_netlink_message_append_u32(req, IFA_FLAGS, address->flags);
851c9f82 816 if (r < 0)
7750b796 817 return log_link_error_errno(link, r, "Could not set extended flags: %m");
851c9f82
PF
818 }
819
5c1d3fc9 820 r = sd_rtnl_message_addr_set_scope(req, address->scope);
eb56eb9b 821 if (r < 0)
7750b796 822 return log_link_error_errno(link, r, "Could not set scope: %m");
5a723174 823
43409486 824 r = netlink_message_append_in_addr_union(req, IFA_LOCAL, address->family, &address->in_addr);
eb56eb9b 825 if (r < 0)
7750b796 826 return log_link_error_errno(link, r, "Could not append IFA_LOCAL attribute: %m");
f579559b 827
d40b01e4 828 if (in_addr_is_null(address->family, &address->in_addr_peer) == 0) {
43409486 829 r = netlink_message_append_in_addr_union(req, IFA_ADDRESS, address->family, &address->in_addr_peer);
eb56eb9b 830 if (r < 0)
7750b796 831 return log_link_error_errno(link, r, "Could not append IFA_ADDRESS attribute: %m");
66e0bb33
YW
832 } else if (address->family == AF_INET && address->prefixlen <= 30) {
833 r = sd_netlink_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
834 if (r < 0)
7750b796 835 return log_link_error_errno(link, r, "Could not append IFA_BROADCAST attribute: %m");
f579559b
TG
836 }
837
838 if (address->label) {
1c4baffc 839 r = sd_netlink_message_append_string(req, IFA_LABEL, address->label);
eb56eb9b 840 if (r < 0)
7750b796 841 return log_link_error_errno(link, r, "Could not append IFA_LABEL attribute: %m");
f579559b
TG
842 }
843
66e0bb33 844 r = sd_netlink_message_append_cache_info(req, IFA_CACHEINFO, &address->cinfo);
eb56eb9b 845 if (r < 0)
7750b796 846 return log_link_error_errno(link, r, "Could not append IFA_CACHEINFO attribute: %m");
68ceb9df 847
fcf50cff 848 r = address_establish(address, link);
eb56eb9b 849 if (r < 0)
7750b796 850 log_link_warning_errno(link, r, "Could not enable IP masquerading, ignoring: %m");
fcf50cff 851
dfef713f 852 r = netlink_call_async(link->manager->rtnl, NULL, req, callback, link_netlink_destroy_callback, link);
fcf50cff
TG
853 if (r < 0) {
854 address_release(address);
7750b796 855 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
fcf50cff 856 }
f579559b 857
563c69c6
TG
858 link_ref(link);
859
dfef713f 860 if (address->family == AF_INET6 && !in_addr_is_null(address->family, &address->in_addr_peer))
80b0e860 861 r = address_add(link, address->family, &address->in_addr_peer, address->prefixlen, &a);
dfef713f 862 else
80b0e860 863 r = address_add(link, address->family, &address->in_addr, address->prefixlen, &a);
adda1ed9
TG
864 if (r < 0) {
865 address_release(address);
7750b796 866 return log_link_error_errno(link, r, "Could not add address: %m");
adda1ed9
TG
867 }
868
051e77ca
SS
869 if (address->acd) {
870 assert(address->family == AF_INET);
871 if (DEBUG_LOGGING) {
872 _cleanup_free_ char *pretty = NULL;
873
874 (void) in_addr_to_string(address->family, &address->in_addr, &pretty);
98b02994 875 log_link_debug(link, "Starting IPv4ACD client. Probing address %s", strna(pretty));
051e77ca
SS
876 }
877
e92b60b2 878 r = sd_ipv4acd_start(address->acd, true);
051e77ca
SS
879 if (r < 0)
880 log_link_warning_errno(link, r, "Failed to start IPv4ACD client, ignoring: %m");
881 }
882
80b0e860
YW
883 if (ret)
884 *ret = a;
885
54a1a535 886 return 1;
f579559b
TG
887}
888
682c65b0
YW
889static int static_address_ready_callback(Address *address) {
890 Address *a;
891 Link *link;
892
893 assert(address);
894 assert(address->link);
895
896 link = address->link;
897
898 if (!link->addresses_configured)
899 return 0;
900
901 SET_FOREACH(a, link->static_addresses)
902 if (!address_is_ready(a)) {
903 _cleanup_free_ char *str = NULL;
904
905 (void) in_addr_to_string(a->family, &a->in_addr, &str);
906 log_link_debug(link, "an address %s/%u is not ready", strnull(str), a->prefixlen);
907 return 0;
908 }
909
910 /* This should not be called again */
911 SET_FOREACH(a, link->static_addresses)
912 a->callback = NULL;
913
914 link->addresses_ready = true;
915
916 return link_set_routes(link);
917}
918
919static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
920 int r;
921
922 assert(rtnl);
923 assert(m);
924 assert(link);
925 assert(link->ifname);
926 assert(link->address_messages > 0);
927 assert(IN_SET(link->state, LINK_STATE_CONFIGURING,
928 LINK_STATE_FAILED, LINK_STATE_LINGER));
929
930 link->address_messages--;
931
932 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
933 return 1;
934
935 r = sd_netlink_message_get_errno(m);
936 if (r < 0 && r != -EEXIST) {
937 log_link_message_warning_errno(link, m, r, "Could not set address");
938 link_enter_failed(link);
939 return 1;
940 } else if (r >= 0)
941 (void) manager_rtnl_process_address(rtnl, m, link->manager);
942
943 if (link->address_messages == 0) {
944 Address *a;
945
946 log_link_debug(link, "Addresses set");
947 link->addresses_configured = true;
948
949 /* When all static addresses are already ready, then static_address_ready_callback()
950 * will not be called automatically. So, call it here. */
951 a = set_first(link->static_addresses);
952 if (!a) {
953 log_link_warning(link, "No static address is stored.");
954 link_enter_failed(link);
955 return 1;
956 }
957 if (!a->callback) {
958 log_link_warning(link, "Address ready callback is not set.");
959 link_enter_failed(link);
960 return 1;
961 }
962 r = a->callback(a);
963 if (r < 0)
964 link_enter_failed(link);
965 }
966
967 return 1;
968}
969
970static int static_address_configure(Address *address, Link *link, bool update) {
971 Address *ret;
972 int r;
973
974 assert(address);
975 assert(link);
976
977 r = address_configure(address, link, address_handler, update, &ret);
978 if (r < 0)
979 return log_link_warning_errno(link, r, "Could not configure static address: %m");
980
981 link->address_messages++;
982
983 r = set_ensure_put(&link->static_addresses, &address_hash_ops, ret);
984 if (r < 0)
985 return log_link_warning_errno(link, r, "Failed to store static address: %m");
986
987 ret->callback = static_address_ready_callback;
988
989 return 0;
990}
991
992int link_set_addresses(Link *link) {
993 Address *ad;
994 int r;
995
996 assert(link);
997 assert(link->network);
998
999 if (link->address_remove_messages != 0) {
1000 log_link_debug(link, "Removing old addresses, new addresses will be configured later.");
1001 link->request_static_addresses = true;
1002 return 0;
1003 }
1004
1005 LIST_FOREACH(addresses, ad, link->network->static_addresses) {
1006 bool update;
1007
1008 if (ad->family == AF_INET6 && !in_addr_is_null(ad->family, &ad->in_addr_peer))
1009 update = address_get(link, ad->family, &ad->in_addr_peer, ad->prefixlen, NULL) > 0;
1010 else
1011 update = address_get(link, ad->family, &ad->in_addr, ad->prefixlen, NULL) > 0;
1012
1013 r = static_address_configure(ad, link, update);
1014 if (r < 0)
1015 return r;
1016 }
1017
1018 if (link->network->router_prefix_delegation & RADV_PREFIX_DELEGATION_STATIC) {
1019 Prefix *p;
1020
1021 HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
1022 _cleanup_(address_freep) Address *address = NULL;
1023
1024 if (!p->assign)
1025 continue;
1026
1027 r = address_new(&address);
1028 if (r < 0)
1029 return log_oom();
1030
1031 r = sd_radv_prefix_get_prefix(p->radv_prefix, &address->in_addr.in6, &address->prefixlen);
1032 if (r < 0)
1033 return log_link_warning_errno(link, r, "Could not get RA prefix: %m");
1034
1035 r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
1036 if (r < 0)
1037 return log_link_warning_errno(link, r, "Could not generate EUI64 address: %m");
1038
1039 address->family = AF_INET6;
1040 r = static_address_configure(address, link, true);
1041 if (r < 0)
1042 return r;
1043 }
1044 }
1045
1046 if (link->address_messages == 0) {
1047 link->addresses_configured = true;
1048 link->addresses_ready = true;
1049 r = link_set_routes(link);
1050 if (r < 0)
1051 return r;
1052 } else {
1053 log_link_debug(link, "Setting addresses");
1054 link_set_state(link, LINK_STATE_CONFIGURING);
1055 }
1056
1057 return 0;
1058}
1059
e1fc2c43
YW
1060int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
1061 _cleanup_free_ char *buf = NULL;
1062 Link *link = NULL;
1063 uint16_t type;
1064 unsigned char flags, prefixlen, scope;
1065 union in_addr_union in_addr = IN_ADDR_NULL;
1066 struct ifa_cacheinfo cinfo;
1067 Address *address = NULL;
1068 char valid_buf[FORMAT_TIMESPAN_MAX];
1069 const char *valid_str = NULL;
1070 int ifindex, family, r;
1071
1072 assert(rtnl);
1073 assert(message);
1074 assert(m);
1075
1076 if (sd_netlink_message_is_error(message)) {
1077 r = sd_netlink_message_get_errno(message);
1078 if (r < 0)
1079 log_message_warning_errno(message, r, "rtnl: failed to receive address message, ignoring");
1080
1081 return 0;
1082 }
1083
1084 r = sd_netlink_message_get_type(message, &type);
1085 if (r < 0) {
1086 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
1087 return 0;
1088 } else if (!IN_SET(type, RTM_NEWADDR, RTM_DELADDR)) {
1089 log_warning("rtnl: received unexpected message type %u when processing address, ignoring.", type);
1090 return 0;
1091 }
1092
1093 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1094 if (r < 0) {
1095 log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m");
1096 return 0;
1097 } else if (ifindex <= 0) {
1098 log_warning("rtnl: received address message with invalid ifindex %d, ignoring.", ifindex);
1099 return 0;
1100 }
1101
1102 r = link_get(m, ifindex, &link);
1103 if (r < 0 || !link) {
1104 /* when enumerating we might be out of sync, but we will get the address again, so just
1105 * ignore it */
1106 if (!m->enumerating)
1107 log_warning("rtnl: received address for link '%d' we don't know about, ignoring.", ifindex);
1108 return 0;
1109 }
1110
1111 r = sd_rtnl_message_addr_get_family(message, &family);
1112 if (r < 0) {
1113 log_link_warning(link, "rtnl: received address message without family, ignoring.");
1114 return 0;
1115 } else if (!IN_SET(family, AF_INET, AF_INET6)) {
1116 log_link_debug(link, "rtnl: received address message with invalid family '%i', ignoring.", family);
1117 return 0;
1118 }
1119
1120 r = sd_rtnl_message_addr_get_prefixlen(message, &prefixlen);
1121 if (r < 0) {
9a0ad16b 1122 log_link_warning_errno(link, r, "rtnl: received address message without prefixlen, ignoring: %m");
e1fc2c43
YW
1123 return 0;
1124 }
1125
1126 r = sd_rtnl_message_addr_get_scope(message, &scope);
1127 if (r < 0) {
9a0ad16b 1128 log_link_warning_errno(link, r, "rtnl: received address message without scope, ignoring: %m");
e1fc2c43
YW
1129 return 0;
1130 }
1131
1132 r = sd_rtnl_message_addr_get_flags(message, &flags);
1133 if (r < 0) {
9a0ad16b 1134 log_link_warning_errno(link, r, "rtnl: received address message without flags, ignoring: %m");
e1fc2c43
YW
1135 return 0;
1136 }
1137
1138 switch (family) {
1139 case AF_INET:
1140 r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &in_addr.in);
1141 if (r < 0) {
1142 log_link_warning_errno(link, r, "rtnl: received address message without valid address, ignoring: %m");
1143 return 0;
1144 }
1145
1146 break;
1147
1148 case AF_INET6:
1149 r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &in_addr.in6);
1150 if (r < 0) {
1151 log_link_warning_errno(link, r, "rtnl: received address message without valid address, ignoring: %m");
1152 return 0;
1153 }
1154
1155 break;
1156
1157 default:
1158 assert_not_reached("Received unsupported address family");
1159 }
1160
9a0ad16b 1161 (void) in_addr_to_string(family, &in_addr, &buf);
e1fc2c43
YW
1162
1163 r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo);
1164 if (r < 0 && r != -ENODATA) {
1165 log_link_warning_errno(link, r, "rtnl: cannot get IFA_CACHEINFO attribute, ignoring: %m");
1166 return 0;
1167 } else if (r >= 0 && cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
1168 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
1169 cinfo.ifa_valid * USEC_PER_SEC,
1170 USEC_PER_SEC);
1171
1172 (void) address_get(link, family, &in_addr, prefixlen, &address);
1173
1174 switch (type) {
1175 case RTM_NEWADDR:
1176 if (address)
1177 log_link_debug(link, "Remembering updated address: %s/%u (valid %s%s)",
1178 strnull(buf), prefixlen,
1179 valid_str ? "for " : "forever", strempty(valid_str));
1180 else {
1181 /* An address appeared that we did not request */
1182 r = address_add_foreign(link, family, &in_addr, prefixlen, &address);
1183 if (r < 0) {
1184 log_link_warning_errno(link, r, "Failed to remember foreign address %s/%u, ignoring: %m",
1185 strnull(buf), prefixlen);
1186 return 0;
1187 } else
1188 log_link_debug(link, "Remembering foreign address: %s/%u (valid %s%s)",
1189 strnull(buf), prefixlen,
1190 valid_str ? "for " : "forever", strempty(valid_str));
1191 }
1192
1193 /* address_update() logs internally, so we don't need to here. */
1194 r = address_update(address, flags, scope, &cinfo);
1195 if (r < 0)
1196 link_enter_failed(link);
1197
1198 break;
1199
1200 case RTM_DELADDR:
1201 if (address) {
1202 log_link_debug(link, "Forgetting address: %s/%u (valid %s%s)",
1203 strnull(buf), prefixlen,
1204 valid_str ? "for " : "forever", strempty(valid_str));
1205 (void) address_drop(address);
1206 } else
1207 log_link_debug(link, "Kernel removed an address we don't remember: %s/%u (valid %s%s), ignoring.",
1208 strnull(buf), prefixlen,
1209 valid_str ? "for " : "forever", strempty(valid_str));
1210
1211 break;
1212
1213 default:
1214 assert_not_reached("Received invalid RTNL message type");
1215 }
1216
1217 return 1;
1218}
1219
3b31e2b7
YW
1220int link_serialize_addresses(Link *link, FILE *f) {
1221 bool space = false;
1222 Address *a;
1223
1224 assert(link);
1225
1226 fputs("ADDRESSES=", f);
1227 SET_FOREACH(a, link->addresses) {
1228 _cleanup_free_ char *address_str = NULL;
1229
1230 if (in_addr_to_string(a->family, &a->in_addr, &address_str) < 0)
1231 continue;
1232
1233 fprintf(f, "%s%s/%u", space ? " " : "", address_str, a->prefixlen);
1234 space = true;
1235 }
1236 fputc('\n', f);
1237
1238 return 0;
1239}
1240
da4d3a61
YW
1241int link_deserialize_addresses(Link *link, const char *addresses) {
1242 int r;
1243
1244 assert(link);
1245
1246 for (const char *p = addresses;; ) {
1247 _cleanup_free_ char *address_str = NULL;
1248 union in_addr_union address;
1249 unsigned char prefixlen;
1250 char *prefixlen_str;
1251 int family;
1252
1253 r = extract_first_word(&p, &address_str, NULL, 0);
1254 if (r < 0)
1255 return log_link_debug_errno(link, r, "Failed to parse ADDRESSES=: %m");
1256 if (r == 0)
1257 return 0;
1258
1259 prefixlen_str = strchr(address_str, '/');
1260 if (!prefixlen_str) {
1261 log_link_debug(link, "Failed to parse address and prefix length, ignoring: %s", address_str);
1262 continue;
1263 }
1264 *prefixlen_str++ = '\0';
1265
1266 r = sscanf(prefixlen_str, "%hhu", &prefixlen);
1267 if (r != 1) {
1268 log_link_debug(link, "Failed to parse prefixlen: %s", prefixlen_str);
1269 continue;
1270 }
1271
1272 r = in_addr_from_string_auto(address_str, &family, &address);
1273 if (r < 0) {
1274 log_link_debug_errno(link, r, "Failed to parse address: %s", address_str);
1275 continue;
1276 }
1277
1278 r = address_add(link, family, &address, prefixlen, NULL);
1279 if (r < 0)
1280 log_link_debug_errno(link, r, "Failed to add address: %m");
1281 }
1282
1283 return 0;
1284}
1285
051e77ca
SS
1286static void static_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
1287 _cleanup_free_ char *pretty = NULL;
1288 Address *address;
1289 Link *link;
1290 int r;
1291
1292 assert(acd);
1293 assert(userdata);
1294
1295 address = (Address *) userdata;
1296 link = address->link;
1297
1298 (void) in_addr_to_string(address->family, &address->in_addr, &pretty);
1299 switch (event) {
1300 case SD_IPV4ACD_EVENT_STOP:
1301 log_link_debug(link, "Stopping ACD client...");
1302 return;
1303
1304 case SD_IPV4ACD_EVENT_BIND:
1305 log_link_debug(link, "Successfully claimed address %s", strna(pretty));
1306 link_check_ready(link);
1307 break;
1308
1309 case SD_IPV4ACD_EVENT_CONFLICT:
1310 log_link_warning(link, "DAD conflict. Dropping address %s", strna(pretty));
1311 r = address_remove(address, link, NULL);
1312 if (r < 0)
1313 log_link_error_errno(link, r, "Failed to drop DAD conflicted address %s", strna(pretty));;
1314
1315 link_check_ready(link);
1316 break;
1317
1318 default:
1319 assert_not_reached("Invalid IPv4ACD event.");
1320 }
1321
1322 sd_ipv4acd_stop(acd);
1323
1324 return;
1325}
1326
b87d6a82 1327static int ipv4_dad_configure(Link *link, Address *address) {
051e77ca
SS
1328 int r;
1329
1330 assert(link);
1331 assert(address);
1332 assert(address->family == AF_INET);
1333 assert(!address->link && address->network);
1334
1335 address->link = link;
1336
1337 r = sd_ipv4acd_new(&address->acd);
1338 if (r < 0)
1339 return r;
1340
1341 r = sd_ipv4acd_attach_event(address->acd, NULL, 0);
1342 if (r < 0)
1343 return r;
1344
1345 r = sd_ipv4acd_set_ifindex(address->acd, link->ifindex);
1346 if (r < 0)
1347 return r;
1348
1349 r = sd_ipv4acd_set_mac(address->acd, &link->mac);
1350 if (r < 0)
1351 return r;
1352
1353 r = sd_ipv4acd_set_address(address->acd, &address->in_addr.in);
1354 if (r < 0)
1355 return r;
1356
1357 r = sd_ipv4acd_set_callback(address->acd, static_address_on_acd, address);
1358 if (r < 0)
1359 return r;
1360
1361 return 0;
1362}
1363
b87d6a82
YW
1364int link_configure_ipv4_dad(Link *link) {
1365 Address *address;
1366 int r;
1367
1368 assert(link);
1369 assert(link->network);
1370
1371 LIST_FOREACH(addresses, address, link->network->static_addresses)
1372 if (address->family == AF_INET &&
1373 FLAGS_SET(address->duplicate_address_detection, ADDRESS_FAMILY_IPV4)) {
1374 r = ipv4_dad_configure(link, address);
1375 if (r < 0)
1376 return log_link_error_errno(link, r, "Failed to configure IPv4ACD: %m");
1377 }
1378
1379 return 0;
1380}
1381
2488e4d9
YW
1382int link_stop_ipv4_dad(Link *link) {
1383 Address *address;
1384 int k, r = 0;
1385
1386 assert(link);
1387
1388 if (!link->network)
1389 return 0;
1390
1391 LIST_FOREACH(addresses, address, link->network->static_addresses) {
1392 if (!address->acd)
1393 continue;
1394
1395 k = sd_ipv4acd_stop(address->acd);
1396 if (k < 0 && r >= 0)
1397 r = k;
1398 }
1399
1400 return r;
1401}
1402
44e7b949
LP
1403int config_parse_broadcast(
1404 const char *unit,
eb0ea358
TG
1405 const char *filename,
1406 unsigned line,
1407 const char *section,
1408 unsigned section_line,
1409 const char *lvalue,
1410 int ltype,
1411 const char *rvalue,
1412 void *data,
1413 void *userdata) {
44e7b949 1414
eb0ea358 1415 Network *network = userdata;
fcbf4cb7 1416 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
eb0ea358
TG
1417 int r;
1418
1419 assert(filename);
1420 assert(section);
1421 assert(lvalue);
1422 assert(rvalue);
1423 assert(data);
1424
f4859fc7 1425 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1426 if (r == -ENOMEM)
1427 return log_oom();
1428 if (r < 0) {
1429 log_syntax(unit, LOG_WARNING, filename, line, r,
1430 "Failed to allocate new address, ignoring assignment: %m");
1431 return 0;
1432 }
eb0ea358 1433
482e2ac1 1434 if (n->family == AF_INET6) {
d96edb2c 1435 log_syntax(unit, LOG_WARNING, filename, line, 0,
2850cd40 1436 "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue);
482e2ac1
TG
1437 return 0;
1438 }
1439
44e7b949 1440 r = in_addr_from_string(AF_INET, rvalue, (union in_addr_union*) &n->broadcast);
eb0ea358 1441 if (r < 0) {
d96edb2c 1442 log_syntax(unit, LOG_WARNING, filename, line, r,
2850cd40 1443 "Broadcast is invalid, ignoring assignment: %s", rvalue);
eb0ea358
TG
1444 return 0;
1445 }
1446
44e7b949 1447 n->family = AF_INET;
eb0ea358
TG
1448 n = NULL;
1449
1450 return 0;
1451}
1452
f579559b
TG
1453int config_parse_address(const char *unit,
1454 const char *filename,
1455 unsigned line,
1456 const char *section,
71a61510 1457 unsigned section_line,
f579559b
TG
1458 const char *lvalue,
1459 int ltype,
1460 const char *rvalue,
1461 void *data,
1462 void *userdata) {
44e7b949 1463
6ae115c1 1464 Network *network = userdata;
fcbf4cb7 1465 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
44e7b949 1466 union in_addr_union buffer;
b7cb4452 1467 unsigned char prefixlen;
44e7b949 1468 int r, f;
f579559b
TG
1469
1470 assert(filename);
6ae115c1 1471 assert(section);
f579559b
TG
1472 assert(lvalue);
1473 assert(rvalue);
1474 assert(data);
1475
92fe133a
TG
1476 if (streq(section, "Network")) {
1477 /* we are not in an Address section, so treat
1478 * this as the special '0' section */
f4859fc7
SS
1479 r = address_new_static(network, NULL, 0, &n);
1480 } else
1481 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1482 if (r == -ENOMEM)
1483 return log_oom();
1484 if (r < 0) {
1485 log_syntax(unit, LOG_WARNING, filename, line, r,
1486 "Failed to allocate new address, ignoring assignment: %m");
1487 return 0;
1488 }
f579559b
TG
1489
1490 /* Address=address/prefixlen */
0f707207
YW
1491 r = in_addr_prefix_from_string_auto_internal(rvalue, PREFIXLEN_REFUSE, &f, &buffer, &prefixlen);
1492 if (r == -ENOANO) {
d96edb2c 1493 log_syntax(unit, LOG_WARNING, filename, line, r,
0f707207
YW
1494 "An address '%s' is specified without prefix length. "
1495 "The behavior of parsing addresses without prefix length will be changed in the future release. "
1496 "Please specify prefix length explicitly.", rvalue);
1497
1498 r = in_addr_prefix_from_string_auto_internal(rvalue, PREFIXLEN_LEGACY, &f, &buffer, &prefixlen);
1499 }
f579559b 1500 if (r < 0) {
d96edb2c 1501 log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid address '%s', ignoring assignment: %m", rvalue);
f579559b
TG
1502 return 0;
1503 }
1504
44e7b949 1505 if (n->family != AF_UNSPEC && f != n->family) {
d96edb2c 1506 log_syntax(unit, LOG_WARNING, filename, line, 0, "Address is incompatible, ignoring assignment: %s", rvalue);
44e7b949
LP
1507 return 0;
1508 }
1509
c9207ff3
YW
1510 if (in_addr_is_null(f, &buffer)) {
1511 /* Will use address from address pool. Note that for ipv6 case, prefix of the address
1512 * pool is 8, but 40 bit is used by the global ID and 16 bit by the subnet ID. So,
1513 * let's limit the prefix length to 64 or larger. See RFC4193. */
1514 if ((f == AF_INET && prefixlen < 8) ||
1515 (f == AF_INET6 && prefixlen < 64)) {
d96edb2c 1516 log_syntax(unit, LOG_WARNING, filename, line, 0,
c9207ff3
YW
1517 "Null address with invalid prefixlen='%u', ignoring assignment: %s",
1518 prefixlen, rvalue);
1519 return 0;
1520 }
1521 }
1522
44e7b949 1523 n->family = f;
b7cb4452 1524 n->prefixlen = prefixlen;
44e7b949
LP
1525
1526 if (streq(lvalue, "Address"))
1527 n->in_addr = buffer;
1528 else
1529 n->in_addr_peer = buffer;
1530
3681d639 1531 if (n->family == AF_INET && n->broadcast.s_addr == 0 && n->prefixlen <= 30)
fe2e4b69 1532 n->broadcast.s_addr = n->in_addr.in.s_addr | htobe32(0xfffffffflu >> n->prefixlen);
eb0ea358 1533
f579559b
TG
1534 n = NULL;
1535
1536 return 0;
1537}
6ae115c1 1538
d31645ad
LP
1539int config_parse_label(
1540 const char *unit,
6ae115c1
TG
1541 const char *filename,
1542 unsigned line,
1543 const char *section,
1544 unsigned section_line,
1545 const char *lvalue,
1546 int ltype,
1547 const char *rvalue,
1548 void *data,
1549 void *userdata) {
d31645ad 1550
fcbf4cb7 1551 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
d31645ad 1552 Network *network = userdata;
6ae115c1
TG
1553 int r;
1554
1555 assert(filename);
1556 assert(section);
1557 assert(lvalue);
1558 assert(rvalue);
1559 assert(data);
1560
f4859fc7 1561 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1562 if (r == -ENOMEM)
1563 return log_oom();
1564 if (r < 0) {
1565 log_syntax(unit, LOG_WARNING, filename, line, r,
1566 "Failed to allocate new address, ignoring assignment: %m");
1567 return 0;
1568 }
6ae115c1 1569
a87d19fe 1570 if (!address_label_valid(rvalue)) {
d96edb2c 1571 log_syntax(unit, LOG_WARNING, filename, line, 0,
2850cd40 1572 "Interface label is too long or invalid, ignoring assignment: %s", rvalue);
6ae115c1
TG
1573 return 0;
1574 }
1575
d31645ad
LP
1576 r = free_and_strdup(&n->label, rvalue);
1577 if (r < 0)
1578 return log_oom();
6ae115c1
TG
1579
1580 n = NULL;
6ae115c1
TG
1581 return 0;
1582}
ce6c77eb 1583
b5834a0b
SS
1584int config_parse_lifetime(const char *unit,
1585 const char *filename,
1586 unsigned line,
1587 const char *section,
1588 unsigned section_line,
1589 const char *lvalue,
1590 int ltype,
1591 const char *rvalue,
1592 void *data,
1593 void *userdata) {
1594 Network *network = userdata;
fcbf4cb7 1595 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
d2735796 1596 uint32_t k;
b5834a0b
SS
1597 int r;
1598
1599 assert(filename);
1600 assert(section);
1601 assert(lvalue);
1602 assert(rvalue);
1603 assert(data);
1604
f4859fc7 1605 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1606 if (r == -ENOMEM)
1607 return log_oom();
1608 if (r < 0) {
1609 log_syntax(unit, LOG_WARNING, filename, line, r,
1610 "Failed to allocate new address, ignoring assignment: %m");
1611 return 0;
1612 }
b5834a0b 1613
10b20e5a
ZJS
1614 /* We accept only "forever", "infinity", empty, or "0". */
1615 if (STR_IN_SET(rvalue, "forever", "infinity", ""))
33680b0a
YW
1616 k = CACHE_INFO_INFINITY_LIFE_TIME;
1617 else if (streq(rvalue, "0"))
1618 k = 0;
1619 else {
d96edb2c 1620 log_syntax(unit, LOG_WARNING, filename, line, 0,
33680b0a 1621 "Invalid PreferredLifetime= value, ignoring: %s", rvalue);
b5834a0b
SS
1622 return 0;
1623 }
1624
33680b0a 1625 n->cinfo.ifa_prefered = k;
d2735796 1626 TAKE_PTR(n);
b5834a0b
SS
1627
1628 return 0;
1629}
1630
e63be084
SS
1631int config_parse_address_flags(const char *unit,
1632 const char *filename,
1633 unsigned line,
1634 const char *section,
1635 unsigned section_line,
1636 const char *lvalue,
1637 int ltype,
1638 const char *rvalue,
1639 void *data,
1640 void *userdata) {
1641 Network *network = userdata;
fcbf4cb7 1642 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
e63be084
SS
1643 int r;
1644
1645 assert(filename);
1646 assert(section);
1647 assert(lvalue);
1648 assert(rvalue);
1649 assert(data);
1650
f4859fc7 1651 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1652 if (r == -ENOMEM)
1653 return log_oom();
1654 if (r < 0) {
1655 log_syntax(unit, LOG_WARNING, filename, line, r,
1656 "Failed to allocate new address, ignoring assignment: %m");
1657 return 0;
1658 }
e63be084
SS
1659
1660 r = parse_boolean(rvalue);
1661 if (r < 0) {
d96edb2c 1662 log_syntax(unit, LOG_WARNING, filename, line, r,
051e77ca 1663 "Failed to parse %s=, ignoring: %s", lvalue, rvalue);
e63be084
SS
1664 return 0;
1665 }
1666
1667 if (streq(lvalue, "HomeAddress"))
1668 n->home_address = r;
e63be084
SS
1669 else if (streq(lvalue, "ManageTemporaryAddress"))
1670 n->manage_temporary_address = r;
1671 else if (streq(lvalue, "PrefixRoute"))
de697db0
YW
1672 n->prefix_route = !r;
1673 else if (streq(lvalue, "AddPrefixRoute"))
e63be084
SS
1674 n->prefix_route = r;
1675 else if (streq(lvalue, "AutoJoin"))
1676 n->autojoin = r;
2850cd40
YW
1677 else
1678 assert_not_reached("Invalid address flag type.");
e63be084 1679
4aa4c4b0 1680 n = NULL;
e63be084
SS
1681 return 0;
1682}
1683
2959fb07
SS
1684int config_parse_address_scope(const char *unit,
1685 const char *filename,
1686 unsigned line,
1687 const char *section,
1688 unsigned section_line,
1689 const char *lvalue,
1690 int ltype,
1691 const char *rvalue,
1692 void *data,
1693 void *userdata) {
1694 Network *network = userdata;
fcbf4cb7 1695 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
2959fb07
SS
1696 int r;
1697
1698 assert(filename);
1699 assert(section);
1700 assert(lvalue);
1701 assert(rvalue);
1702 assert(data);
1703
1704 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1705 if (r == -ENOMEM)
1706 return log_oom();
1707 if (r < 0) {
1708 log_syntax(unit, LOG_WARNING, filename, line, r,
1709 "Failed to allocate new address, ignoring assignment: %m");
1710 return 0;
1711 }
2959fb07
SS
1712
1713 if (streq(rvalue, "host"))
1714 n->scope = RT_SCOPE_HOST;
1715 else if (streq(rvalue, "link"))
1716 n->scope = RT_SCOPE_LINK;
1717 else if (streq(rvalue, "global"))
1718 n->scope = RT_SCOPE_UNIVERSE;
1719 else {
1720 r = safe_atou8(rvalue , &n->scope);
1721 if (r < 0) {
d96edb2c 1722 log_syntax(unit, LOG_WARNING, filename, line, r,
2850cd40 1723 "Could not parse address scope \"%s\", ignoring assignment: %m", rvalue);
2959fb07
SS
1724 return 0;
1725 }
1726 }
1727
07336a06 1728 n->scope_set = true;
2959fb07 1729 n = NULL;
2959fb07
SS
1730 return 0;
1731}
1732
051e77ca
SS
1733int config_parse_duplicate_address_detection(
1734 const char *unit,
1735 const char *filename,
1736 unsigned line,
1737 const char *section,
1738 unsigned section_line,
1739 const char *lvalue,
1740 int ltype,
1741 const char *rvalue,
1742 void *data,
1743 void *userdata) {
1744 Network *network = userdata;
1745 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
1746 AddressFamily a;
1747 int r;
1748
1749 assert(filename);
1750 assert(section);
1751 assert(lvalue);
1752 assert(rvalue);
1753 assert(data);
1754
1755 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1756 if (r == -ENOMEM)
1757 return log_oom();
1758 if (r < 0) {
1759 log_syntax(unit, LOG_WARNING, filename, line, r,
1760 "Failed to allocate new address, ignoring assignment: %m");
1761 return 0;
1762 }
051e77ca
SS
1763
1764 r = parse_boolean(rvalue);
1765 if (r >= 0) {
1766 log_syntax(unit, LOG_WARNING, filename, line, 0,
1767 "For historical reasons, %s=%s means %s=%s. "
1768 "Please use 'both', 'ipv4', 'ipv6' or 'none' instead.",
1769 lvalue, rvalue, lvalue, r ? "none" : "both");
1770 n->duplicate_address_detection = r ? ADDRESS_FAMILY_NO : ADDRESS_FAMILY_YES;
1771 n = NULL;
1772 return 0;
1773 }
1774
1775 a = duplicate_address_detection_address_family_from_string(rvalue);
1776 if (a < 0) {
d96edb2c 1777 log_syntax(unit, LOG_WARNING, filename, line, SYNTHETIC_ERRNO(EINVAL),
051e77ca
SS
1778 "Failed to parse %s=, ignoring: %s", lvalue, rvalue);
1779 return 0;
1780 }
1781
1782 n->duplicate_address_detection = a;
1783 n = NULL;
1784 return 0;
1785}
1786
ce6c77eb
TG
1787bool address_is_ready(const Address *a) {
1788 assert(a);
1789
ce158189 1790 return !(a->flags & IFA_F_TENTATIVE);
ce6c77eb 1791}
fcbf4cb7 1792
32400c2f 1793static int address_section_verify(Address *address) {
fcbf4cb7
YW
1794 if (section_is_invalid(address->section))
1795 return -EINVAL;
1796
1797 if (address->family == AF_UNSPEC) {
1798 assert(address->section);
1799
1800 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
1801 "%s: Address section without Address= field configured. "
1802 "Ignoring [Address] section from line %u.",
1803 address->section->filename, address->section->line);
1804 }
1805
07336a06
YW
1806 if (!address->scope_set && in_addr_is_localhost(address->family, &address->in_addr) > 0)
1807 address->scope = RT_SCOPE_HOST;
1808
fcbf4cb7
YW
1809 return 0;
1810}
32400c2f
YW
1811
1812void network_verify_addresses(Network *network) {
1813 Address *address, *address_next;
1814
1815 assert(network);
1816
1817 LIST_FOREACH_SAFE(addresses, address, address_next, network->static_addresses)
1818 if (address_section_verify(address) < 0)
1819 address_free(address);
1820}