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