]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-address.c
network: update log messages
[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
113void address_free(Address *address) {
114 if (!address)
115 return;
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);
f579559b
TG
152 free(address);
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
051e77ca
SS
1220static void static_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
1221 _cleanup_free_ char *pretty = NULL;
1222 Address *address;
1223 Link *link;
1224 int r;
1225
1226 assert(acd);
1227 assert(userdata);
1228
1229 address = (Address *) userdata;
1230 link = address->link;
1231
1232 (void) in_addr_to_string(address->family, &address->in_addr, &pretty);
1233 switch (event) {
1234 case SD_IPV4ACD_EVENT_STOP:
1235 log_link_debug(link, "Stopping ACD client...");
1236 return;
1237
1238 case SD_IPV4ACD_EVENT_BIND:
1239 log_link_debug(link, "Successfully claimed address %s", strna(pretty));
1240 link_check_ready(link);
1241 break;
1242
1243 case SD_IPV4ACD_EVENT_CONFLICT:
1244 log_link_warning(link, "DAD conflict. Dropping address %s", strna(pretty));
1245 r = address_remove(address, link, NULL);
1246 if (r < 0)
1247 log_link_error_errno(link, r, "Failed to drop DAD conflicted address %s", strna(pretty));;
1248
1249 link_check_ready(link);
1250 break;
1251
1252 default:
1253 assert_not_reached("Invalid IPv4ACD event.");
1254 }
1255
1256 sd_ipv4acd_stop(acd);
1257
1258 return;
1259}
1260
1261int configure_ipv4_duplicate_address_detection(Link *link, Address *address) {
1262 int r;
1263
1264 assert(link);
1265 assert(address);
1266 assert(address->family == AF_INET);
1267 assert(!address->link && address->network);
1268
1269 address->link = link;
1270
1271 r = sd_ipv4acd_new(&address->acd);
1272 if (r < 0)
1273 return r;
1274
1275 r = sd_ipv4acd_attach_event(address->acd, NULL, 0);
1276 if (r < 0)
1277 return r;
1278
1279 r = sd_ipv4acd_set_ifindex(address->acd, link->ifindex);
1280 if (r < 0)
1281 return r;
1282
1283 r = sd_ipv4acd_set_mac(address->acd, &link->mac);
1284 if (r < 0)
1285 return r;
1286
1287 r = sd_ipv4acd_set_address(address->acd, &address->in_addr.in);
1288 if (r < 0)
1289 return r;
1290
1291 r = sd_ipv4acd_set_callback(address->acd, static_address_on_acd, address);
1292 if (r < 0)
1293 return r;
1294
1295 return 0;
1296}
1297
44e7b949
LP
1298int config_parse_broadcast(
1299 const char *unit,
eb0ea358
TG
1300 const char *filename,
1301 unsigned line,
1302 const char *section,
1303 unsigned section_line,
1304 const char *lvalue,
1305 int ltype,
1306 const char *rvalue,
1307 void *data,
1308 void *userdata) {
44e7b949 1309
eb0ea358 1310 Network *network = userdata;
fcbf4cb7 1311 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
eb0ea358
TG
1312 int r;
1313
1314 assert(filename);
1315 assert(section);
1316 assert(lvalue);
1317 assert(rvalue);
1318 assert(data);
1319
f4859fc7 1320 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1321 if (r == -ENOMEM)
1322 return log_oom();
1323 if (r < 0) {
1324 log_syntax(unit, LOG_WARNING, filename, line, r,
1325 "Failed to allocate new address, ignoring assignment: %m");
1326 return 0;
1327 }
eb0ea358 1328
482e2ac1 1329 if (n->family == AF_INET6) {
d96edb2c 1330 log_syntax(unit, LOG_WARNING, filename, line, 0,
2850cd40 1331 "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue);
482e2ac1
TG
1332 return 0;
1333 }
1334
44e7b949 1335 r = in_addr_from_string(AF_INET, rvalue, (union in_addr_union*) &n->broadcast);
eb0ea358 1336 if (r < 0) {
d96edb2c 1337 log_syntax(unit, LOG_WARNING, filename, line, r,
2850cd40 1338 "Broadcast is invalid, ignoring assignment: %s", rvalue);
eb0ea358
TG
1339 return 0;
1340 }
1341
44e7b949 1342 n->family = AF_INET;
eb0ea358
TG
1343 n = NULL;
1344
1345 return 0;
1346}
1347
f579559b
TG
1348int config_parse_address(const char *unit,
1349 const char *filename,
1350 unsigned line,
1351 const char *section,
71a61510 1352 unsigned section_line,
f579559b
TG
1353 const char *lvalue,
1354 int ltype,
1355 const char *rvalue,
1356 void *data,
1357 void *userdata) {
44e7b949 1358
6ae115c1 1359 Network *network = userdata;
fcbf4cb7 1360 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
44e7b949 1361 union in_addr_union buffer;
b7cb4452 1362 unsigned char prefixlen;
44e7b949 1363 int r, f;
f579559b
TG
1364
1365 assert(filename);
6ae115c1 1366 assert(section);
f579559b
TG
1367 assert(lvalue);
1368 assert(rvalue);
1369 assert(data);
1370
92fe133a
TG
1371 if (streq(section, "Network")) {
1372 /* we are not in an Address section, so treat
1373 * this as the special '0' section */
f4859fc7
SS
1374 r = address_new_static(network, NULL, 0, &n);
1375 } else
1376 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1377 if (r == -ENOMEM)
1378 return log_oom();
1379 if (r < 0) {
1380 log_syntax(unit, LOG_WARNING, filename, line, r,
1381 "Failed to allocate new address, ignoring assignment: %m");
1382 return 0;
1383 }
f579559b
TG
1384
1385 /* Address=address/prefixlen */
0f707207
YW
1386 r = in_addr_prefix_from_string_auto_internal(rvalue, PREFIXLEN_REFUSE, &f, &buffer, &prefixlen);
1387 if (r == -ENOANO) {
d96edb2c 1388 log_syntax(unit, LOG_WARNING, filename, line, r,
0f707207
YW
1389 "An address '%s' is specified without prefix length. "
1390 "The behavior of parsing addresses without prefix length will be changed in the future release. "
1391 "Please specify prefix length explicitly.", rvalue);
1392
1393 r = in_addr_prefix_from_string_auto_internal(rvalue, PREFIXLEN_LEGACY, &f, &buffer, &prefixlen);
1394 }
f579559b 1395 if (r < 0) {
d96edb2c 1396 log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid address '%s', ignoring assignment: %m", rvalue);
f579559b
TG
1397 return 0;
1398 }
1399
44e7b949 1400 if (n->family != AF_UNSPEC && f != n->family) {
d96edb2c 1401 log_syntax(unit, LOG_WARNING, filename, line, 0, "Address is incompatible, ignoring assignment: %s", rvalue);
44e7b949
LP
1402 return 0;
1403 }
1404
c9207ff3
YW
1405 if (in_addr_is_null(f, &buffer)) {
1406 /* Will use address from address pool. Note that for ipv6 case, prefix of the address
1407 * pool is 8, but 40 bit is used by the global ID and 16 bit by the subnet ID. So,
1408 * let's limit the prefix length to 64 or larger. See RFC4193. */
1409 if ((f == AF_INET && prefixlen < 8) ||
1410 (f == AF_INET6 && prefixlen < 64)) {
d96edb2c 1411 log_syntax(unit, LOG_WARNING, filename, line, 0,
c9207ff3
YW
1412 "Null address with invalid prefixlen='%u', ignoring assignment: %s",
1413 prefixlen, rvalue);
1414 return 0;
1415 }
1416 }
1417
44e7b949 1418 n->family = f;
b7cb4452 1419 n->prefixlen = prefixlen;
44e7b949
LP
1420
1421 if (streq(lvalue, "Address"))
1422 n->in_addr = buffer;
1423 else
1424 n->in_addr_peer = buffer;
1425
3681d639 1426 if (n->family == AF_INET && n->broadcast.s_addr == 0 && n->prefixlen <= 30)
fe2e4b69 1427 n->broadcast.s_addr = n->in_addr.in.s_addr | htobe32(0xfffffffflu >> n->prefixlen);
eb0ea358 1428
f579559b
TG
1429 n = NULL;
1430
1431 return 0;
1432}
6ae115c1 1433
d31645ad
LP
1434int config_parse_label(
1435 const char *unit,
6ae115c1
TG
1436 const char *filename,
1437 unsigned line,
1438 const char *section,
1439 unsigned section_line,
1440 const char *lvalue,
1441 int ltype,
1442 const char *rvalue,
1443 void *data,
1444 void *userdata) {
d31645ad 1445
fcbf4cb7 1446 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
d31645ad 1447 Network *network = userdata;
6ae115c1
TG
1448 int r;
1449
1450 assert(filename);
1451 assert(section);
1452 assert(lvalue);
1453 assert(rvalue);
1454 assert(data);
1455
f4859fc7 1456 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1457 if (r == -ENOMEM)
1458 return log_oom();
1459 if (r < 0) {
1460 log_syntax(unit, LOG_WARNING, filename, line, r,
1461 "Failed to allocate new address, ignoring assignment: %m");
1462 return 0;
1463 }
6ae115c1 1464
a87d19fe 1465 if (!address_label_valid(rvalue)) {
d96edb2c 1466 log_syntax(unit, LOG_WARNING, filename, line, 0,
2850cd40 1467 "Interface label is too long or invalid, ignoring assignment: %s", rvalue);
6ae115c1
TG
1468 return 0;
1469 }
1470
d31645ad
LP
1471 r = free_and_strdup(&n->label, rvalue);
1472 if (r < 0)
1473 return log_oom();
6ae115c1
TG
1474
1475 n = NULL;
6ae115c1
TG
1476 return 0;
1477}
ce6c77eb 1478
b5834a0b
SS
1479int config_parse_lifetime(const char *unit,
1480 const char *filename,
1481 unsigned line,
1482 const char *section,
1483 unsigned section_line,
1484 const char *lvalue,
1485 int ltype,
1486 const char *rvalue,
1487 void *data,
1488 void *userdata) {
1489 Network *network = userdata;
fcbf4cb7 1490 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
d2735796 1491 uint32_t k;
b5834a0b
SS
1492 int r;
1493
1494 assert(filename);
1495 assert(section);
1496 assert(lvalue);
1497 assert(rvalue);
1498 assert(data);
1499
f4859fc7 1500 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1501 if (r == -ENOMEM)
1502 return log_oom();
1503 if (r < 0) {
1504 log_syntax(unit, LOG_WARNING, filename, line, r,
1505 "Failed to allocate new address, ignoring assignment: %m");
1506 return 0;
1507 }
b5834a0b 1508
10b20e5a
ZJS
1509 /* We accept only "forever", "infinity", empty, or "0". */
1510 if (STR_IN_SET(rvalue, "forever", "infinity", ""))
33680b0a
YW
1511 k = CACHE_INFO_INFINITY_LIFE_TIME;
1512 else if (streq(rvalue, "0"))
1513 k = 0;
1514 else {
d96edb2c 1515 log_syntax(unit, LOG_WARNING, filename, line, 0,
33680b0a 1516 "Invalid PreferredLifetime= value, ignoring: %s", rvalue);
b5834a0b
SS
1517 return 0;
1518 }
1519
33680b0a 1520 n->cinfo.ifa_prefered = k;
d2735796 1521 TAKE_PTR(n);
b5834a0b
SS
1522
1523 return 0;
1524}
1525
e63be084
SS
1526int config_parse_address_flags(const char *unit,
1527 const char *filename,
1528 unsigned line,
1529 const char *section,
1530 unsigned section_line,
1531 const char *lvalue,
1532 int ltype,
1533 const char *rvalue,
1534 void *data,
1535 void *userdata) {
1536 Network *network = userdata;
fcbf4cb7 1537 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
e63be084
SS
1538 int r;
1539
1540 assert(filename);
1541 assert(section);
1542 assert(lvalue);
1543 assert(rvalue);
1544 assert(data);
1545
f4859fc7 1546 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1547 if (r == -ENOMEM)
1548 return log_oom();
1549 if (r < 0) {
1550 log_syntax(unit, LOG_WARNING, filename, line, r,
1551 "Failed to allocate new address, ignoring assignment: %m");
1552 return 0;
1553 }
e63be084
SS
1554
1555 r = parse_boolean(rvalue);
1556 if (r < 0) {
d96edb2c 1557 log_syntax(unit, LOG_WARNING, filename, line, r,
051e77ca 1558 "Failed to parse %s=, ignoring: %s", lvalue, rvalue);
e63be084
SS
1559 return 0;
1560 }
1561
1562 if (streq(lvalue, "HomeAddress"))
1563 n->home_address = r;
e63be084
SS
1564 else if (streq(lvalue, "ManageTemporaryAddress"))
1565 n->manage_temporary_address = r;
1566 else if (streq(lvalue, "PrefixRoute"))
de697db0
YW
1567 n->prefix_route = !r;
1568 else if (streq(lvalue, "AddPrefixRoute"))
e63be084
SS
1569 n->prefix_route = r;
1570 else if (streq(lvalue, "AutoJoin"))
1571 n->autojoin = r;
2850cd40
YW
1572 else
1573 assert_not_reached("Invalid address flag type.");
e63be084 1574
4aa4c4b0 1575 n = NULL;
e63be084
SS
1576 return 0;
1577}
1578
2959fb07
SS
1579int config_parse_address_scope(const char *unit,
1580 const char *filename,
1581 unsigned line,
1582 const char *section,
1583 unsigned section_line,
1584 const char *lvalue,
1585 int ltype,
1586 const char *rvalue,
1587 void *data,
1588 void *userdata) {
1589 Network *network = userdata;
fcbf4cb7 1590 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
2959fb07
SS
1591 int r;
1592
1593 assert(filename);
1594 assert(section);
1595 assert(lvalue);
1596 assert(rvalue);
1597 assert(data);
1598
1599 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1600 if (r == -ENOMEM)
1601 return log_oom();
1602 if (r < 0) {
1603 log_syntax(unit, LOG_WARNING, filename, line, r,
1604 "Failed to allocate new address, ignoring assignment: %m");
1605 return 0;
1606 }
2959fb07
SS
1607
1608 if (streq(rvalue, "host"))
1609 n->scope = RT_SCOPE_HOST;
1610 else if (streq(rvalue, "link"))
1611 n->scope = RT_SCOPE_LINK;
1612 else if (streq(rvalue, "global"))
1613 n->scope = RT_SCOPE_UNIVERSE;
1614 else {
1615 r = safe_atou8(rvalue , &n->scope);
1616 if (r < 0) {
d96edb2c 1617 log_syntax(unit, LOG_WARNING, filename, line, r,
2850cd40 1618 "Could not parse address scope \"%s\", ignoring assignment: %m", rvalue);
2959fb07
SS
1619 return 0;
1620 }
1621 }
1622
07336a06 1623 n->scope_set = true;
2959fb07 1624 n = NULL;
2959fb07
SS
1625 return 0;
1626}
1627
051e77ca
SS
1628int config_parse_duplicate_address_detection(
1629 const char *unit,
1630 const char *filename,
1631 unsigned line,
1632 const char *section,
1633 unsigned section_line,
1634 const char *lvalue,
1635 int ltype,
1636 const char *rvalue,
1637 void *data,
1638 void *userdata) {
1639 Network *network = userdata;
1640 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
1641 AddressFamily a;
1642 int r;
1643
1644 assert(filename);
1645 assert(section);
1646 assert(lvalue);
1647 assert(rvalue);
1648 assert(data);
1649
1650 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1651 if (r == -ENOMEM)
1652 return log_oom();
1653 if (r < 0) {
1654 log_syntax(unit, LOG_WARNING, filename, line, r,
1655 "Failed to allocate new address, ignoring assignment: %m");
1656 return 0;
1657 }
051e77ca
SS
1658
1659 r = parse_boolean(rvalue);
1660 if (r >= 0) {
1661 log_syntax(unit, LOG_WARNING, filename, line, 0,
1662 "For historical reasons, %s=%s means %s=%s. "
1663 "Please use 'both', 'ipv4', 'ipv6' or 'none' instead.",
1664 lvalue, rvalue, lvalue, r ? "none" : "both");
1665 n->duplicate_address_detection = r ? ADDRESS_FAMILY_NO : ADDRESS_FAMILY_YES;
1666 n = NULL;
1667 return 0;
1668 }
1669
1670 a = duplicate_address_detection_address_family_from_string(rvalue);
1671 if (a < 0) {
d96edb2c 1672 log_syntax(unit, LOG_WARNING, filename, line, SYNTHETIC_ERRNO(EINVAL),
051e77ca
SS
1673 "Failed to parse %s=, ignoring: %s", lvalue, rvalue);
1674 return 0;
1675 }
1676
1677 n->duplicate_address_detection = a;
1678 n = NULL;
1679 return 0;
1680}
1681
ce6c77eb
TG
1682bool address_is_ready(const Address *a) {
1683 assert(a);
1684
ce158189 1685 return !(a->flags & IFA_F_TENTATIVE);
ce6c77eb 1686}
fcbf4cb7
YW
1687
1688int address_section_verify(Address *address) {
1689 if (section_is_invalid(address->section))
1690 return -EINVAL;
1691
1692 if (address->family == AF_UNSPEC) {
1693 assert(address->section);
1694
1695 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
1696 "%s: Address section without Address= field configured. "
1697 "Ignoring [Address] section from line %u.",
1698 address->section->filename, address->section->line);
1699 }
1700
07336a06
YW
1701 if (!address->scope_set && in_addr_is_localhost(address->family, &address->in_addr) > 0)
1702 address->scope = RT_SCOPE_HOST;
1703
fcbf4cb7
YW
1704 return 0;
1705}