]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-address.c
network/address: do not set configuring flag when a request is canceled
[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"
3ae6b3bf 8#include "logarithm.h"
0a970718 9#include "memory-util.h"
fc2f9534 10#include "netlink-util.h"
bfbf150e 11#include "networkd-address-pool.h"
6bedfcbb 12#include "networkd-address.h"
3b6a3bde 13#include "networkd-dhcp-server.h"
76a86ffd 14#include "networkd-ipv4acd.h"
23f53b99 15#include "networkd-manager.h"
4b3590c3 16#include "networkd-netlabel.h"
093e3533 17#include "networkd-network.h"
76c5a0f2 18#include "networkd-queue.h"
d8c472f2 19#include "networkd-route-util.h"
3b6a3bde 20#include "networkd-route.h"
6bedfcbb 21#include "parse-util.h"
07630cea 22#include "string-util.h"
51517f9e 23#include "strv.h"
0fd97a25 24#include "strxcpyx.h"
f579559b 25
1b566071 26#define ADDRESSES_PER_LINK_MAX 2048U
8c34b963
LP
27#define STATIC_ADDRESSES_PER_NETWORK_MAX 1024U
28
b1179a5d
YW
29#define KNOWN_FLAGS \
30 (IFA_F_SECONDARY | \
31 IFA_F_NODAD | \
32 IFA_F_OPTIMISTIC | \
33 IFA_F_DADFAILED | \
34 IFA_F_HOMEADDRESS | \
35 IFA_F_DEPRECATED | \
36 IFA_F_TENTATIVE | \
37 IFA_F_PERMANENT | \
38 IFA_F_MANAGETEMPADDR | \
39 IFA_F_NOPREFIXROUTE | \
40 IFA_F_MCAUTOJOIN | \
41 IFA_F_STABLE_PRIVACY)
42
43/* From net/ipv4/devinet.c */
44#define IPV6ONLY_FLAGS \
45 (IFA_F_NODAD | \
46 IFA_F_OPTIMISTIC | \
47 IFA_F_DADFAILED | \
48 IFA_F_HOMEADDRESS | \
49 IFA_F_TENTATIVE | \
50 IFA_F_MANAGETEMPADDR | \
51 IFA_F_STABLE_PRIVACY)
52
53/* We do not control the following flags. */
54#define UNMANAGED_FLAGS \
55 (IFA_F_SECONDARY | \
56 IFA_F_DADFAILED | \
57 IFA_F_DEPRECATED | \
58 IFA_F_TENTATIVE | \
59 IFA_F_PERMANENT | \
60 IFA_F_STABLE_PRIVACY)
61
42ceb474 62int address_flags_to_string_alloc(uint32_t flags, int family, char **ret) {
a2362484 63 _cleanup_free_ char *str = NULL;
7396e014
ZJS
64 static const char* map[] = {
65 [LOG2U(IFA_F_SECONDARY)] = "secondary", /* This is also called "temporary" for ipv6. */
66 [LOG2U(IFA_F_NODAD)] = "nodad",
67 [LOG2U(IFA_F_OPTIMISTIC)] = "optimistic",
68 [LOG2U(IFA_F_DADFAILED)] = "dadfailed",
69 [LOG2U(IFA_F_HOMEADDRESS)] = "home-address",
70 [LOG2U(IFA_F_DEPRECATED)] = "deprecated",
71 [LOG2U(IFA_F_TENTATIVE)] = "tentative",
72 [LOG2U(IFA_F_PERMANENT)] = "permanent",
73 [LOG2U(IFA_F_MANAGETEMPADDR)] = "manage-temporary-address",
74 [LOG2U(IFA_F_NOPREFIXROUTE)] = "no-prefixroute",
75 [LOG2U(IFA_F_MCAUTOJOIN)] = "auto-join",
76 [LOG2U(IFA_F_STABLE_PRIVACY)] = "stable-privacy",
a2362484
YW
77 };
78
79 assert(IN_SET(family, AF_INET, AF_INET6));
80 assert(ret);
81
0828a386 82 for (size_t i = 0; i < ELEMENTSOF(map); i++)
7396e014
ZJS
83 if (FLAGS_SET(flags, 1 << i) && map[i])
84 if (!strextend_with_separator(
85 &str, ",",
86 family == AF_INET6 && (1 << i) == IFA_F_SECONDARY ? "temporary" : map[i]))
87 return -ENOMEM;
a2362484
YW
88
89 *ret = TAKE_PTR(str);
90 return 0;
91}
92
f0213e37 93int address_new(Address **ret) {
8e766630 94 _cleanup_(address_freep) Address *address = NULL;
f0213e37 95
17f9c355 96 address = new(Address, 1);
f0213e37
TG
97 if (!address)
98 return -ENOMEM;
aba496a5 99
17f9c355
YW
100 *address = (Address) {
101 .family = AF_UNSPEC,
102 .scope = RT_SCOPE_UNIVERSE,
16bc8635
YW
103 .lifetime_valid_usec = USEC_INFINITY,
104 .lifetime_preferred_usec = USEC_INFINITY,
832583ad 105 .set_broadcast = -1,
17f9c355 106 };
f0213e37 107
1cc6c93a 108 *ret = TAKE_PTR(address);
f0213e37
TG
109
110 return 0;
aba496a5
UTL
111}
112
9560e5b3 113static int address_new_static(Network *network, const char *filename, unsigned section_line, Address **ret) {
307fe3cd 114 _cleanup_(config_section_freep) ConfigSection *n = NULL;
8e766630 115 _cleanup_(address_freep) Address *address = NULL;
f0213e37 116 int r;
f579559b 117
8c34b963
LP
118 assert(network);
119 assert(ret);
9cd9fc8f
YW
120 assert(filename);
121 assert(section_line > 0);
f4859fc7 122
307fe3cd 123 r = config_section_new(filename, section_line, &n);
9cd9fc8f
YW
124 if (r < 0)
125 return r;
6ae115c1 126
9cd9fc8f
YW
127 address = ordered_hashmap_get(network->addresses_by_section, n);
128 if (address) {
129 *ret = TAKE_PTR(address);
130 return 0;
6ae115c1
TG
131 }
132
9cd9fc8f 133 if (ordered_hashmap_size(network->addresses_by_section) >= STATIC_ADDRESSES_PER_NETWORK_MAX)
8c34b963
LP
134 return -E2BIG;
135
f0213e37
TG
136 r = address_new(&address);
137 if (r < 0)
138 return r;
801bd9e8 139
0f7f2769 140 address->network = network;
9cd9fc8f 141 address->section = TAKE_PTR(n);
3b6a3bde 142 address->source = NETWORK_CONFIG_SOURCE_STATIC;
2859932b
YW
143 /* This will be adjusted in address_section_verify(). */
144 address->duplicate_address_detection = _ADDRESS_FAMILY_INVALID;
0f7f2769 145
307fe3cd 146 r = ordered_hashmap_ensure_put(&network->addresses_by_section, &config_section_hash_ops, address->section, address);
9cd9fc8f
YW
147 if (r < 0)
148 return r;
6ae115c1 149
1cc6c93a 150 *ret = TAKE_PTR(address);
f579559b
TG
151 return 0;
152}
153
7818f858 154Address *address_free(Address *address) {
f579559b 155 if (!address)
7818f858 156 return NULL;
f579559b 157
f048a16b 158 if (address->network) {
9cd9fc8f
YW
159 assert(address->section);
160 ordered_hashmap_remove(address->network->addresses_by_section, address->section);
f048a16b 161 }
6ae115c1 162
490ccbd5 163 if (address->link) {
cf1d700d 164 set_remove(address->link->addresses, address);
f150100a 165
94876904
YW
166 if (address->family == AF_INET6 &&
167 in6_addr_equal(&address->in_addr.in6, &address->link->ipv6ll_address))
f150100a 168 memzero(&address->link->ipv6ll_address, sizeof(struct in6_addr));
cf1d700d 169
5385e5f9
YW
170 ipv4acd_detach(address->link, address);
171 }
051e77ca 172
307fe3cd 173 config_section_free(address->section);
de4224aa 174 free(address->label);
4b3590c3 175 free(address->netlabel);
7818f858 176 return mfree(address);
f579559b
TG
177}
178
dc32de39
YW
179static bool address_lifetime_is_valid(const Address *a) {
180 assert(a);
181
182 return
183 a->lifetime_valid_usec == USEC_INFINITY ||
184 a->lifetime_valid_usec > now(CLOCK_BOOTTIME);
185}
186
3b6a3bde
YW
187bool address_is_ready(const Address *a) {
188 assert(a);
5385e5f9 189 assert(a->link);
3b6a3bde 190
5385e5f9 191 if (!ipv4acd_bound(a->link, a))
3b6a3bde
YW
192 return false;
193
e402e99e 194 if (FLAGS_SET(a->flags, IFA_F_TENTATIVE))
3b6a3bde
YW
195 return false;
196
e402e99e 197 if (FLAGS_SET(a->state, NETWORK_CONFIG_STATE_REMOVING))
3b6a3bde
YW
198 return false;
199
200 if (!FLAGS_SET(a->state, NETWORK_CONFIG_STATE_CONFIGURED))
201 return false;
202
dc32de39 203 return address_lifetime_is_valid(a);
3b6a3bde
YW
204}
205
5f950e56
YW
206bool link_check_addresses_ready(Link *link, NetworkConfigSource source) {
207 Address *a;
208 bool has = false;
209
210 assert(link);
211
212 /* Check if all addresses on the interface are ready. If there is no address, this will return false. */
213
214 SET_FOREACH(a, link->addresses) {
215 if (source >= 0 && a->source != source)
216 continue;
217 if (address_is_marked(a))
218 continue;
219 if (!address_exists(a))
220 continue;
221 if (!address_is_ready(a))
222 return false;
223 has = true;
224 }
225
226 return has;
227}
228
2ccada8d 229void link_mark_addresses(Link *link, NetworkConfigSource source) {
3b6a3bde
YW
230 Address *a;
231
232 assert(link);
233
234 SET_FOREACH(a, link->addresses) {
235 if (a->source != source)
236 continue;
237
3b6a3bde
YW
238 address_mark(a);
239 }
240}
241
1a1f4a80
YW
242int address_get_broadcast(const Address *a, Link *link, struct in_addr *ret) {
243 struct in_addr b_addr = {};
244
2a236f9f 245 assert(a);
e680486d 246 assert(link);
2a236f9f 247
1a1f4a80
YW
248 /* Returns 0 when broadcast address is null, 1 when non-null broadcast address, -EAGAIN when the main
249 * address is null. */
250
251 /* broadcast is only for IPv4. */
473680be 252 if (a->family != AF_INET)
1a1f4a80 253 goto finalize;
473680be 254
1a1f4a80 255 /* broadcast address cannot be used when peer address is specified. */
473680be 256 if (in4_addr_is_set(&a->in_addr_peer.in))
1a1f4a80 257 goto finalize;
473680be 258
2a236f9f
YW
259 /* A /31 or /32 IPv4 address does not have a broadcast address.
260 * See https://tools.ietf.org/html/rfc3021 */
473680be 261 if (a->prefixlen > 30)
1a1f4a80 262 goto finalize;
473680be 263
1a1f4a80
YW
264 /* If explicitly configured, use the address as is. */
265 if (in4_addr_is_set(&a->broadcast)) {
266 b_addr = a->broadcast;
267 goto finalize;
268 }
473680be 269
1a1f4a80
YW
270 /* If explicitly disabled, then return null address. */
271 if (a->set_broadcast == 0)
272 goto finalize;
473680be 273
1a1f4a80
YW
274 /* For wireguard interfaces, broadcast is disabled by default. */
275 if (a->set_broadcast < 0 && streq_ptr(link->kind, "wireguard"))
276 goto finalize;
2a236f9f 277
1a1f4a80
YW
278 /* If the main address is null, e.g. Address=0.0.0.0/24, the broadcast address will be automatically
279 * determined after an address is acquired. */
280 if (!in4_addr_is_set(&a->in_addr.in))
281 return -EAGAIN;
282
283 /* Otherwise, generate a broadcast address from the main address and prefix length. */
284 b_addr.s_addr = a->in_addr.in.s_addr | htobe32(UINT32_C(0xffffffff) >> a->prefixlen);
832583ad 285
1a1f4a80
YW
286finalize:
287 if (ret)
288 *ret = b_addr;
832583ad 289
1a1f4a80 290 return in4_addr_is_set(&b_addr);
832583ad
YW
291}
292
b9e4ec50 293static void address_set_cinfo(Manager *m, const Address *a, struct ifa_cacheinfo *cinfo) {
16bc8635
YW
294 usec_t now_usec;
295
def4741b 296 assert(m);
16bc8635
YW
297 assert(a);
298 assert(cinfo);
299
def4741b 300 assert_se(sd_event_now(m->event, CLOCK_BOOTTIME, &now_usec) >= 0);
16bc8635
YW
301
302 *cinfo = (struct ifa_cacheinfo) {
5235d739
YW
303 .ifa_valid = usec_to_sec(a->lifetime_valid_usec, now_usec),
304 .ifa_prefered = usec_to_sec(a->lifetime_preferred_usec, now_usec),
16bc8635 305 };
16bc8635
YW
306}
307
def4741b 308static void address_set_lifetime(Manager *m, Address *a, const struct ifa_cacheinfo *cinfo) {
16bc8635
YW
309 usec_t now_usec;
310
def4741b 311 assert(m);
16bc8635
YW
312 assert(a);
313 assert(cinfo);
314
def4741b 315 assert_se(sd_event_now(m->event, CLOCK_BOOTTIME, &now_usec) >= 0);
16bc8635 316
5235d739
YW
317 a->lifetime_valid_usec = sec_to_usec(cinfo->ifa_valid, now_usec);
318 a->lifetime_preferred_usec = sec_to_usec(cinfo->ifa_prefered, now_usec);
16bc8635
YW
319}
320
d0009d92
YW
321static bool address_is_static_null(const Address *address) {
322 assert(address);
323
324 if (!address->network)
325 return false;
326
327 if (!address->requested_as_null)
328 return false;
329
330 assert(!in_addr_is_set(address->family, &address->in_addr));
331 return true;
332}
333
1d30fc5c
YW
334static uint32_t address_prefix(const Address *a) {
335 assert(a);
336
337 /* make sure we don't try to shift by 32.
338 * See ISO/IEC 9899:TC3 § 6.5.7.3. */
339 if (a->prefixlen == 0)
340 return 0;
341
342 if (a->in_addr_peer.in.s_addr != 0)
343 return be32toh(a->in_addr_peer.in.s_addr) >> (32 - a->prefixlen);
344 else
345 return be32toh(a->in_addr.in.s_addr) >> (32 - a->prefixlen);
346}
347
5d003031 348static void address_kernel_hash_func(const Address *a, struct siphash *state) {
3ac8e543
TG
349 assert(a);
350
351 siphash24_compress(&a->family, sizeof(a->family), state);
352
1d30fc5c
YW
353 switch (a->family) {
354 case AF_INET:
355 siphash24_compress(&a->prefixlen, sizeof(a->prefixlen), state);
3ac8e543 356
1d30fc5c
YW
357 uint32_t prefix = address_prefix(a);
358 siphash24_compress(&prefix, sizeof(prefix), state);
3ac8e543 359
1d30fc5c
YW
360 _fallthrough_;
361 case AF_INET6:
362 siphash24_compress(&a->in_addr, FAMILY_ADDRESS_SIZE(a->family), state);
363 break;
364 default:
365 /* treat any other address family as AF_UNSPEC */
366 break;
367 }
3ac8e543
TG
368}
369
5d003031 370static int address_kernel_compare_func(const Address *a1, const Address *a2) {
a0edd02e 371 int r;
3ac8e543 372
a0edd02e
FB
373 r = CMP(a1->family, a2->family);
374 if (r != 0)
375 return r;
3ac8e543 376
1d30fc5c
YW
377 switch (a1->family) {
378 case AF_INET:
379 /* See kernel's find_matching_ifa() in net/ipv4/devinet.c */
380 r = CMP(a1->prefixlen, a2->prefixlen);
24be9181
ZJS
381 if (r != 0)
382 return r;
3ac8e543 383
1d30fc5c
YW
384 r = CMP(address_prefix(a1), address_prefix(a2));
385 if (r != 0)
386 return r;
2a236f9f 387
1d30fc5c
YW
388 _fallthrough_;
389 case AF_INET6:
390 /* See kernel's ipv6_get_ifaddr() in net/ipv6/addrconf.c */
391 return memcmp(&a1->in_addr, &a2->in_addr, FAMILY_ADDRESS_SIZE(a1->family));
392 default:
393 /* treat any other address family as AF_UNSPEC */
394 return 0;
395 }
3ac8e543
TG
396}
397
50783f91 398DEFINE_PRIVATE_HASH_OPS(
5d003031 399 address_kernel_hash_ops,
50783f91 400 Address,
5d003031
YW
401 address_kernel_hash_func,
402 address_kernel_compare_func);
403
42f8b6a8
YW
404DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
405 address_kernel_hash_ops_free,
406 Address,
407 address_kernel_hash_func,
408 address_kernel_compare_func,
409 address_free);
410
5d003031
YW
411int address_compare_func(const Address *a1, const Address *a2) {
412 int r;
413
414 r = CMP(a1->family, a2->family);
415 if (r != 0)
416 return r;
417
418 if (!IN_SET(a1->family, AF_INET, AF_INET6))
419 return 0;
420
421 r = CMP(a1->prefixlen, a2->prefixlen);
422 if (r != 0)
423 return r;
424
425 r = memcmp(&a1->in_addr, &a2->in_addr, FAMILY_ADDRESS_SIZE(a1->family));
426 if (r != 0)
427 return r;
428
429 r = memcmp(&a1->in_addr_peer, &a2->in_addr_peer, FAMILY_ADDRESS_SIZE(a1->family));
430 if (r != 0)
431 return r;
432
390247d2 433 if (a1->family == AF_INET) {
0b8b30f6
YW
434 /* On update, the kernel ignores the address label and broadcast address, hence we need
435 * to distinguish addresses with different labels or broadcast addresses. Otherwise,
436 * the label or broadcast address change will not be applied when we reconfigure the
437 * interface. */
390247d2
YW
438 r = strcmp_ptr(a1->label, a2->label);
439 if (r != 0)
440 return r;
441
442 r = CMP(a1->broadcast.s_addr, a2->broadcast.s_addr);
443 if (r != 0)
444 return r;
445 }
446
5d003031
YW
447 return 0;
448}
50783f91 449
42f8b6a8
YW
450int address_equal(const Address *a1, const Address *a2) {
451 if (a1 == a2)
452 return true;
453
454 if (!a1 || !a2)
455 return false;
456
457 return address_compare_func(a1, a2) == 0;
458}
459
99b46669
YW
460int address_dup(const Address *src, Address **ret) {
461 _cleanup_(address_freep) Address *dest = NULL;
cde1f0e8
YW
462 int r;
463
cde1f0e8 464 assert(src);
99b46669
YW
465 assert(ret);
466
467 dest = newdup(Address, src, 1);
468 if (!dest)
469 return -ENOMEM;
470
471 /* clear all pointers */
472 dest->network = NULL;
473 dest->section = NULL;
474 dest->link = NULL;
475 dest->label = NULL;
4b3590c3 476 dest->netlabel = NULL;
cde1f0e8 477
2a236f9f
YW
478 if (src->family == AF_INET) {
479 r = free_and_strdup(&dest->label, src->label);
480 if (r < 0)
481 return r;
482 }
cde1f0e8 483
4b3590c3
TM
484 r = free_and_strdup(&dest->netlabel, src->netlabel);
485 if (r < 0)
486 return r;
487
99b46669 488 *ret = TAKE_PTR(dest);
cde1f0e8
YW
489 return 0;
490}
491
494b6b43
YW
492static int address_set_masquerade(Address *address, bool add) {
493 union in_addr_union masked;
91b5f997
TG
494 int r;
495
496 assert(address);
494b6b43 497 assert(address->link);
91b5f997 498
494b6b43
YW
499 if (!address->link->network)
500 return 0;
91b5f997 501
48ed2766
FW
502 if (address->family == AF_INET &&
503 !FLAGS_SET(address->link->network->ip_masquerade, ADDRESS_FAMILY_IPV4))
494b6b43 504 return 0;
91b5f997 505
48ed2766
FW
506 if (address->family == AF_INET6 &&
507 !FLAGS_SET(address->link->network->ip_masquerade, ADDRESS_FAMILY_IPV6))
494b6b43 508 return 0;
91b5f997 509
494b6b43
YW
510 if (address->scope >= RT_SCOPE_LINK)
511 return 0;
512
da0e2bae 513 if (address->ip_masquerade_done == add)
494b6b43
YW
514 return 0;
515
516 masked = address->in_addr;
517 r = in_addr_mask(address->family, &masked, address->prefixlen);
518 if (r < 0)
519 return r;
520
48ed2766 521 r = fw_add_masquerade(&address->link->manager->fw_ctx, add, address->family, &masked, address->prefixlen);
494b6b43
YW
522 if (r < 0)
523 return r;
524
da0e2bae 525 address->ip_masquerade_done = add;
91b5f997
TG
526
527 return 0;
528}
529
3b6a3bde 530static int address_add(Link *link, Address *address) {
cf1d700d
TG
531 int r;
532
533 assert(link);
3b6a3bde 534 assert(address);
cf1d700d 535
42f8b6a8 536 r = set_ensure_put(&link->addresses, &address_kernel_hash_ops_free, address);
cf1d700d
TG
537 if (r < 0)
538 return r;
75a302b5
YW
539 if (r == 0)
540 return -EEXIST;
cf1d700d
TG
541
542 address->link = link;
7b3a7581 543 return 0;
adda1ed9
TG
544}
545
f9831557 546static int address_update(Address *address) {
4bbe559b 547 Link *link = ASSERT_PTR(ASSERT_PTR(address)->link);
e7ab854c 548 int r;
36c32f61 549
7657ec3e
YW
550 if (address_is_ready(address) &&
551 address->family == AF_INET6 &&
552 in6_addr_is_link_local(&address->in_addr.in6) &&
553 in6_addr_is_null(&link->ipv6ll_address)) {
554
555 link->ipv6ll_address = address->in_addr.in6;
556
557 r = link_ipv6ll_gained(link);
558 if (r < 0)
559 return r;
560 }
561
2c40a889 562 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
ea121d8f
YW
563 return 0;
564
4bbe559b 565 r = address_set_masquerade(address, /* add = */ true);
7a8685ff
YW
566 if (r < 0)
567 return log_link_warning_errno(link, r, "Could not enable IP masquerading: %m");
568
4b3590c3
TM
569 address_add_netlabel(address);
570
981fab5d
YW
571 if (address_is_ready(address) && address->callback) {
572 r = address->callback(address);
573 if (r < 0)
574 return r;
a3a019e1 575 }
36c32f61 576
4bbe559b 577 link_update_operstate(link, /* also_update_master = */ true);
981fab5d 578 link_check_ready(link);
36c32f61
TG
579 return 0;
580}
581
67a58eb3 582static int address_drop(Address *address) {
4bbe559b 583 Link *link = ASSERT_PTR(ASSERT_PTR(address)->link);
7750b796 584 int r;
8012cd39 585
4bbe559b 586 r = address_set_masquerade(address, /* add = */ false);
7750b796
YW
587 if (r < 0)
588 log_link_warning_errno(link, r, "Failed to disable IP masquerading, ignoring: %m");
589
4b3590c3
TM
590 address_del_netlabel(address);
591
0a0c2672 592 address_free(address);
91b5f997 593
aaad20e0
YW
594 link_update_operstate(link, /* also_update_master = */ true);
595 link_check_ready(link);
91b5f997
TG
596 return 0;
597}
598
a2532c9d
YW
599static bool address_match_null(const Address *a, const Address *null_address) {
600 assert(a);
601 assert(null_address);
602
603 if (!a->requested_as_null)
604 return false;
605
606 /* Currently, null address is supported only by static addresses. Note that static
607 * address may be set as foreign during reconfiguring the interface. */
608 if (!IN_SET(a->source, NETWORK_CONFIG_SOURCE_FOREIGN, NETWORK_CONFIG_SOURCE_STATIC))
609 return false;
610
611 if (a->family != null_address->family)
612 return false;
613
614 if (a->prefixlen != null_address->prefixlen)
615 return false;
616
617 return true;
618}
619
0a0c2672
YW
620static int address_get_request(Link *link, const Address *address, Request **ret) {
621 Request *req;
622
623 assert(link);
624 assert(link->manager);
625 assert(address);
626
627 req = ordered_set_get(
628 link->manager->request_queue,
629 &(Request) {
630 .link = link,
631 .type = REQUEST_TYPE_ADDRESS,
632 .userdata = (void*) address,
633 .hash_func = (hash_func_t) address_kernel_hash_func,
634 .compare_func = (compare_func_t) address_kernel_compare_func,
635 });
636 if (req) {
637 if (ret)
638 *ret = req;
639 return 0;
640 }
641
642 if (address_is_static_null(address))
643 ORDERED_SET_FOREACH(req, link->manager->request_queue) {
644 if (req->link != link)
645 continue;
646 if (req->type != REQUEST_TYPE_ADDRESS)
647 continue;
648
649 if (!address_match_null(req->userdata, address))
650 continue;
651
652 if (ret)
653 *ret = req;
654
655 return 0;
656 }
657
658 return -ENOENT;
659}
660
fe841414 661int address_get(Link *link, const Address *in, Address **ret) {
d0009d92 662 Address *a;
91b5f997 663
5a8bcb67 664 assert(link);
fe841414 665 assert(in);
5a8bcb67 666
d0009d92
YW
667 a = set_get(link->addresses, in);
668 if (a) {
669 if (ret)
670 *ret = a;
671 return 0;
672 }
673
674 /* Find matching address that originally requested as null address. */
675 if (address_is_static_null(in))
676 SET_FOREACH(a, link->addresses) {
a2532c9d 677 if (!address_match_null(a, in))
d0009d92
YW
678 continue;
679
680 if (ret)
681 *ret = a;
682 return 0;
683 }
684
685 return -ENOENT;
5a8bcb67
LP
686}
687
b33dd04e
YW
688int address_get_harder(Link *link, const Address *in, Address **ret) {
689 Request *req;
690 int r;
691
692 assert(link);
693 assert(in);
694
695 if (address_get(link, in, ret) >= 0)
696 return 0;
697
698 r = address_get_request(link, in, &req);
699 if (r < 0)
700 return r;
701
702 if (ret)
703 *ret = ASSERT_PTR(req->userdata);
704
705 return 0;
706}
707
5d003031 708int link_get_address(Link *link, int family, const union in_addr_union *address, unsigned char prefixlen, Address **ret) {
390247d2 709 Address *a;
c5a0aeb3 710 int r;
5eec0a08 711
c5a0aeb3 712 assert(link);
5d003031 713 assert(IN_SET(family, AF_INET, AF_INET6));
c5a0aeb3 714 assert(address);
5eec0a08 715
5d003031
YW
716 /* This find an Address object on the link which matches the given address and prefix length
717 * and does not have peer address. When the prefixlen is zero, then an Address object with an
718 * arbitrary prefixlen will be returned. */
998545a7 719
42f8b6a8 720 if (family == AF_INET6 || prefixlen != 0) {
390247d2 721 _cleanup_(address_freep) Address *tmp = NULL;
998545a7 722
42f8b6a8 723 /* In this case, we can use address_get(). */
998545a7 724
390247d2 725 r = address_new(&tmp);
998545a7
YW
726 if (r < 0)
727 return r;
728
390247d2
YW
729 tmp->family = family;
730 tmp->in_addr = *address;
731 tmp->prefixlen = prefixlen;
3b6a3bde 732
42f8b6a8
YW
733 r = address_get(link, tmp, &a);
734 if (r < 0)
735 return r;
3b6a3bde 736
42f8b6a8
YW
737 if (family == AF_INET6) {
738 /* IPv6 addresses are managed without peer address and prefix length. Hence, we need
739 * to check them explicitly. */
740 if (in_addr_is_set(family, &a->in_addr_peer))
741 return -ENOENT;
742 if (prefixlen != 0 && a->prefixlen != prefixlen)
743 return -ENOENT;
3b6a3bde
YW
744 }
745
42f8b6a8
YW
746 if (ret)
747 *ret = a;
390247d2 748
42f8b6a8 749 return 0;
390247d2
YW
750 }
751
752 SET_FOREACH(a, link->addresses) {
753 if (a->family != family)
754 continue;
755
756 if (!in_addr_equal(family, &a->in_addr, address))
757 continue;
758
759 if (in_addr_is_set(family, &a->in_addr_peer))
760 continue;
761
762 if (ret)
763 *ret = a;
764
765 return 0;
3b6a3bde 766 }
390247d2
YW
767
768 return -ENOENT;
998545a7
YW
769}
770
77e9be1e 771int manager_get_address(Manager *manager, int family, const union in_addr_union *address, unsigned char prefixlen, Address **ret) {
591bd5f3 772 Link *link;
591bd5f3
YW
773
774 assert(manager);
775 assert(IN_SET(family, AF_INET, AF_INET6));
776 assert(address);
777
77e9be1e
YW
778 HASHMAP_FOREACH(link, manager->links_by_index) {
779 if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
780 continue;
781
782 if (link_get_address(link, family, address, prefixlen, ret) >= 0)
783 return 0;
784 }
785
786 return -ENOENT;
787}
788
789bool manager_has_address(Manager *manager, int family, const union in_addr_union *address, bool check_ready) {
790 Address *a;
791
792 assert(manager);
793 assert(IN_SET(family, AF_INET, AF_INET6));
794 assert(address);
795
796 if (manager_get_address(manager, family, address, 0, &a) < 0)
797 return false;
591bd5f3 798
dc32de39 799 return check_ready ? address_is_ready(a) : (address_exists(a) && address_lifetime_is_valid(a));
591bd5f3
YW
800}
801
16bc8635 802const char* format_lifetime(char *buf, size_t l, usec_t lifetime_usec) {
0fd97a25 803 assert(buf);
a35f3128 804 assert(l > 4);
0fd97a25 805
16bc8635 806 if (lifetime_usec == USEC_INFINITY)
a35f3128 807 return "forever";
0fd97a25 808
a35f3128
ZJS
809 sprintf(buf, "for ");
810 /* format_timespan() never fails */
ba4e0427 811 assert_se(format_timespan(buf + 4, l - 4, usec_sub_unsigned(lifetime_usec, now(CLOCK_BOOTTIME)), USEC_PER_SEC));
a35f3128 812 return buf;
0fd97a25
YW
813}
814
24f50382 815static void log_address_debug(const Address *address, const char *str, const Link *link) {
84dbb3fd 816 _cleanup_free_ char *state = NULL, *flags_str = NULL, *scope_str = NULL;
7653a9dc 817
24f50382
YW
818 assert(address);
819 assert(str);
820 assert(link);
821
7653a9dc
YW
822 if (!DEBUG_LOGGING)
823 return;
824
3b6a3bde 825 (void) network_config_state_to_string_alloc(address->state, &state);
84dbb3fd
ZJS
826
827 const char *peer = in_addr_is_set(address->family, &address->in_addr_peer) ?
828 IN_ADDR_TO_STRING(address->family, &address->in_addr_peer) : NULL;
7653a9dc 829
14044a41
YW
830 const char *broadcast = (address->family == AF_INET && in4_addr_is_set(&address->broadcast)) ?
831 IN4_ADDR_TO_STRING(&address->broadcast) : NULL;
832
a2362484 833 (void) address_flags_to_string_alloc(address->flags, address->family, &flags_str);
78ef25a5 834 (void) route_scope_to_string_alloc(address->scope, &scope_str);
a2362484 835
14044a41 836 log_link_debug(link, "%s %s address (%s): %s%s%s/%u%s%s (valid %s, preferred %s), flags: %s, scope: %s%s%s",
3b6a3bde 837 str, strna(network_config_source_to_string(address->source)), strna(state),
84dbb3fd
ZJS
838 IN_ADDR_TO_STRING(address->family, &address->in_addr),
839 peer ? " peer " : "", strempty(peer), address->prefixlen,
14044a41 840 broadcast ? " broadcast " : "", strempty(broadcast),
16bc8635
YW
841 FORMAT_LIFETIME(address->lifetime_valid_usec),
842 FORMAT_LIFETIME(address->lifetime_preferred_usec),
14044a41
YW
843 strna(flags_str), strna(scope_str),
844 address->family == AF_INET ? ", label: " : "",
845 address->family == AF_INET ? strna(address->label) : "");
24f50382
YW
846}
847
a79a8d16 848static int address_set_netlink_message(const Address *address, sd_netlink_message *m, Link *link) {
d5e3b3eb 849 uint32_t flags;
a8481354
YW
850 int r;
851
852 assert(address);
a79a8d16 853 assert(m);
a8481354
YW
854 assert(link);
855
a79a8d16 856 r = sd_rtnl_message_addr_set_prefixlen(m, address->prefixlen);
a8481354 857 if (r < 0)
a79a8d16 858 return r;
a8481354
YW
859
860 /* On remove, only IFA_F_MANAGETEMPADDR flag for IPv6 addresses are used. But anyway, set all
d5e3b3eb
YW
861 * flags except tentative flag here unconditionally. Without setting the flag, the template
862 * addresses generated by kernel will not be removed automatically when the main address is
863 * removed. */
864 flags = address->flags & ~IFA_F_TENTATIVE;
a79a8d16 865 r = sd_rtnl_message_addr_set_flags(m, flags & 0xff);
a8481354 866 if (r < 0)
a79a8d16 867 return r;
a8481354 868
d5e3b3eb 869 if ((flags & ~0xff) != 0) {
a79a8d16 870 r = sd_netlink_message_append_u32(m, IFA_FLAGS, flags);
a8481354 871 if (r < 0)
a79a8d16 872 return r;
a8481354
YW
873 }
874
a79a8d16 875 r = netlink_message_append_in_addr_union(m, IFA_LOCAL, address->family, &address->in_addr);
a8481354 876 if (r < 0)
a79a8d16 877 return r;
a8481354
YW
878
879 return 0;
880}
881
f4cc1364 882static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
5a07fa9d
YW
883 int r;
884
5a07fa9d
YW
885 assert(m);
886 assert(link);
76c5a0f2 887
5a07fa9d
YW
888 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
889 return 0;
890
891 r = sd_netlink_message_get_errno(m);
892 if (r < 0 && r != -EADDRNOTAVAIL)
f4cc1364 893 log_link_message_warning_errno(link, m, r, "Could not drop address");
5a07fa9d
YW
894
895 return 1;
896}
897
3b6a3bde 898int address_remove(Address *address) {
a79a8d16 899 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
0a0c2672 900 Request *req;
3b6a3bde 901 Link *link;
407fe036
TG
902 int r;
903
904 assert(address);
4c701096 905 assert(IN_SET(address->family, AF_INET, AF_INET6));
3b6a3bde
YW
906 assert(address->link);
907 assert(address->link->ifindex > 0);
908 assert(address->link->manager);
909 assert(address->link->manager->rtnl);
910
911 link = address->link;
407fe036 912
24f50382 913 log_address_debug(address, "Removing", link);
30226d27 914
a79a8d16 915 r = sd_rtnl_message_new_addr(link->manager->rtnl, &m, RTM_DELADDR,
151b9b96 916 link->ifindex, address->family);
eb56eb9b 917 if (r < 0)
a79a8d16 918 return log_link_warning_errno(link, r, "Could not allocate RTM_DELADDR message: %m");
407fe036 919
a79a8d16 920 r = address_set_netlink_message(address, m, link);
eb56eb9b 921 if (r < 0)
a79a8d16 922 return log_link_warning_errno(link, r, "Could not set netlink attributes: %m");
407fe036 923
a79a8d16 924 r = netlink_call_async(link->manager->rtnl, NULL, m,
f4cc1364 925 address_remove_handler,
302a796f 926 link_netlink_destroy_callback, link);
eb56eb9b 927 if (r < 0)
a79a8d16 928 return log_link_warning_errno(link, r, "Could not send rtnetlink message: %m");
407fe036 929
563c69c6
TG
930 link_ref(link);
931
3b6a3bde 932 address_enter_removing(address);
0a0c2672
YW
933 if (address_get_request(link, address, &req) >= 0)
934 address_enter_removing(req->userdata);
613d65d8
YW
935
936 /* The operational state is determined by address state and carrier state. Hence, if we remove
937 * an address, the operational state may be changed. */
938 link_update_operstate(link, true);
407fe036
TG
939 return 0;
940}
941
d4b76314
YW
942int address_remove_and_drop(Address *address) {
943 if (!address)
944 return 0;
945
946 address_cancel_request(address);
947
948 if (address_exists(address))
949 return address_remove(address);
950
951 return address_drop(address);
952}
953
3def8850 954bool link_address_is_dynamic(const Link *link, const Address *address) {
f8f2f880
YW
955 Route *route;
956
957 assert(link);
958 assert(address);
959
16bc8635 960 if (address->lifetime_preferred_usec != USEC_INFINITY)
f8f2f880
YW
961 return true;
962
963 /* Even when the address is leased from a DHCP server, networkd assign the address
964 * without lifetime when KeepConfiguration=dhcp. So, let's check that we have
965 * corresponding routes with RTPROT_DHCP. */
3b6a3bde
YW
966 SET_FOREACH(route, link->routes) {
967 if (route->source != NETWORK_CONFIG_SOURCE_FOREIGN)
968 continue;
969
f974f17a
YW
970 /* The route is not assigned yet, or already removed. Ignoring. */
971 if (!route_exists(route))
972 continue;
973
f8f2f880
YW
974 if (route->protocol != RTPROT_DHCP)
975 continue;
976
977 if (address->family != route->family)
978 continue;
979
980 if (in_addr_equal(address->family, &address->in_addr, &route->prefsrc))
981 return true;
982 }
983
984 return false;
985}
986
b9bf3f22 987int link_drop_ipv6ll_addresses(Link *link) {
51f5dfd8 988 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
51f5dfd8
YW
989 int r;
990
991 assert(link);
992 assert(link->manager);
993 assert(link->manager->rtnl);
994
b9bf3f22
YW
995 /* IPv6LL address may be in the tentative state, and in that case networkd has not received it.
996 * So, we need to dump all IPv6 addresses. */
997
bd7e0a3f 998 if (link_may_have_ipv6ll(link, /* check_multicast = */ false))
b9bf3f22
YW
999 return 0;
1000
c31298be 1001 r = sd_rtnl_message_new_addr(link->manager->rtnl, &req, RTM_GETADDR, link->ifindex, AF_INET6);
51f5dfd8
YW
1002 if (r < 0)
1003 return r;
1004
24c0f385 1005 r = sd_netlink_message_set_request_dump(req, true);
f318f643
YW
1006 if (r < 0)
1007 return r;
1008
51f5dfd8
YW
1009 r = sd_netlink_call(link->manager->rtnl, req, 0, &reply);
1010 if (r < 0)
1011 return r;
1012
cda7fc8d 1013 for (sd_netlink_message *addr = reply; addr; addr = sd_netlink_message_next(addr)) {
b9bf3f22
YW
1014 _cleanup_(address_freep) Address *a = NULL;
1015 unsigned char flags, prefixlen;
1016 struct in6_addr address;
3b6a3bde 1017 Address *existing;
51f5dfd8
YW
1018 int ifindex;
1019
c31298be
YW
1020 /* NETLINK_GET_STRICT_CHK socket option is supported since kernel 4.20. To support
1021 * older kernels, we need to check ifindex here. */
51f5dfd8
YW
1022 r = sd_rtnl_message_addr_get_ifindex(addr, &ifindex);
1023 if (r < 0) {
b9bf3f22 1024 log_link_debug_errno(link, r, "rtnl: received address message without valid ifindex, ignoring: %m");
51f5dfd8
YW
1025 continue;
1026 } else if (link->ifindex != ifindex)
1027 continue;
1028
1029 r = sd_rtnl_message_addr_get_flags(addr, &flags);
1030 if (r < 0) {
b9bf3f22
YW
1031 log_link_debug_errno(link, r, "rtnl: received address message without valid flags, ignoring: %m");
1032 continue;
1033 }
1034
1035 r = sd_rtnl_message_addr_get_prefixlen(addr, &prefixlen);
1036 if (r < 0) {
1037 log_link_debug_errno(link, r, "rtnl: received address message without prefixlen, ignoring: %m");
51f5dfd8 1038 continue;
b9bf3f22
YW
1039 }
1040
1041 if (sd_netlink_message_read_in6_addr(addr, IFA_LOCAL, NULL) >= 0)
1042 /* address with peer, ignoring. */
51f5dfd8
YW
1043 continue;
1044
b9bf3f22
YW
1045 r = sd_netlink_message_read_in6_addr(addr, IFA_ADDRESS, &address);
1046 if (r < 0) {
1047 log_link_debug_errno(link, r, "rtnl: received address message without valid address, ignoring: %m");
1048 continue;
1049 }
1050
1051 if (!in6_addr_is_link_local(&address))
1052 continue;
1053
1054 r = address_new(&a);
1055 if (r < 0)
1056 return -ENOMEM;
1057
1058 a->family = AF_INET6;
1059 a->in_addr.in6 = address;
1060 a->prefixlen = prefixlen;
1061 a->flags = flags;
1062
3b6a3bde
YW
1063 if (address_get(link, a, &existing) < 0) {
1064 r = address_add(link, a);
1065 if (r < 0)
1066 return r;
1067
1068 existing = TAKE_PTR(a);
1069 }
1070
1071 r = address_remove(existing);
b9bf3f22
YW
1072 if (r < 0)
1073 return r;
51f5dfd8
YW
1074 }
1075
1076 return 0;
1077}
1078
f8f2f880
YW
1079int link_drop_foreign_addresses(Link *link) {
1080 Address *address;
1339b950 1081 int r = 0;
f8f2f880
YW
1082
1083 assert(link);
3b6a3bde 1084 assert(link->network);
f8f2f880 1085
3b6a3bde
YW
1086 /* First, mark all addresses. */
1087 SET_FOREACH(address, link->addresses) {
b9bf3f22 1088 /* We consider IPv6LL addresses to be managed by the kernel, or dropped in link_drop_ipv6ll_addresses() */
ecedc48b 1089 if (address->family == AF_INET6 && in6_addr_is_link_local(&address->in_addr.in6))
f8f2f880
YW
1090 continue;
1091
b69bfa43
YW
1092 /* Do not remove localhost address (127.0.0.1 and ::1) */
1093 if (link->flags & IFF_LOOPBACK && in_addr_is_localhost_one(address->family, &address->in_addr) > 0)
1094 continue;
1095
3b6a3bde
YW
1096 /* Ignore addresses we configured. */
1097 if (address->source != NETWORK_CONFIG_SOURCE_FOREIGN)
1098 continue;
1099
1100 /* Ignore addresses not assigned yet or already removing. */
1101 if (!address_exists(address))
1102 continue;
1103
a71c5c44
YW
1104 /* link_address_is_dynamic() is slightly heavy. Let's call the function only when KeepConfiguration= is set. */
1105 if (IN_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP, KEEP_CONFIGURATION_STATIC) &&
1106 link_address_is_dynamic(link, address) == (link->network->keep_configuration == KEEP_CONFIGURATION_DHCP))
f8f2f880
YW
1107 continue;
1108
3b6a3bde
YW
1109 address_mark(address);
1110 }
1111
1112 /* Then, unmark requested addresses. */
1113 ORDERED_HASHMAP_FOREACH(address, link->network->addresses_by_section) {
1114 Address *existing;
1115
d0009d92
YW
1116 if (address_get(link, address, &existing) < 0)
1117 continue;
1118
42f8b6a8
YW
1119 /* On update, the kernel ignores the address label and broadcast address. Hence we need to
1120 * distinguish addresses with different labels or broadcast addresses. Thus, we need to check
1121 * the existing address with address_equal(). Otherwise, the label or broadcast address
1122 * change will not be applied when we reconfigure the interface. */
d0009d92
YW
1123 if (address_is_static_null(address)) {
1124 /* If the static configuration has null address, then the broadcast address will be
1125 * determined automatically. Hence, here we need to compare only address label. */
1126 if (address->family == AF_INET && !streq_ptr(address->label, existing->label))
1127 continue;
1128
1129 } else if (!address_equal(address, existing))
1130 continue;
1131
1132 /* Found matching static configuration. Keep the existing address. */
1133 address_unmark(existing);
3b6a3bde
YW
1134 }
1135
1136 /* Finally, remove all marked addresses. */
1137 SET_FOREACH(address, link->addresses) {
1138 if (!address_is_marked(address))
1139 continue;
1140
1339b950 1141 RET_GATHER(r, address_remove(address));
f8f2f880
YW
1142 }
1143
1144 return r;
1145}
1146
a0e99a37 1147int link_drop_managed_addresses(Link *link) {
3b6a3bde 1148 Address *address;
1339b950 1149 int r = 0;
d7fbb9f5
YW
1150
1151 assert(link);
1152
1153 SET_FOREACH(address, link->addresses) {
a0e99a37
YW
1154 /* Do not touch addresses managed by kernel or other tools. */
1155 if (address->source == NETWORK_CONFIG_SOURCE_FOREIGN)
3b6a3bde
YW
1156 continue;
1157
a0e99a37
YW
1158 /* Ignore addresses not assigned yet or already removing. */
1159 if (!address_exists(address))
d7fbb9f5
YW
1160 continue;
1161
1339b950 1162 RET_GATHER(r, address_remove(address));
d7fbb9f5
YW
1163 }
1164
1165 return r;
1166}
1167
b4564f4e
YW
1168void link_foreignize_addresses(Link *link) {
1169 Address *address;
1170
1171 assert(link);
1172
1173 SET_FOREACH(address, link->addresses)
1174 address->source = NETWORK_CONFIG_SOURCE_FOREIGN;
1175}
1176
693ec5ca 1177static int address_acquire(Link *link, const Address *original, Address **ret) {
8e766630 1178 _cleanup_(address_freep) Address *na = NULL;
3b6a3bde 1179 union in_addr_union in_addr;
11bf3cce
LP
1180 int r;
1181
1182 assert(link);
1183 assert(original);
1184 assert(ret);
1185
1186 /* Something useful was configured? just use it */
9684a8de
YW
1187 if (in_addr_is_set(original->family, &original->in_addr))
1188 return address_dup(original, ret);
11bf3cce
LP
1189
1190 /* The address is configured to be 0.0.0.0 or [::] by the user?
1191 * Then let's acquire something more useful from the pool. */
ed76f585 1192 r = address_pool_acquire(link->manager, original->family, original->prefixlen, &in_addr);
6a7a4e4d 1193 if (r < 0)
7750b796
YW
1194 return r;
1195 if (r == 0)
11bf3cce 1196 return -EBUSY;
11bf3cce 1197
473680be
YW
1198 /* Pick first address in range for ourselves. */
1199 if (original->family == AF_INET)
11bf3cce 1200 in_addr.in.s_addr = in_addr.in.s_addr | htobe32(1);
473680be 1201 else if (original->family == AF_INET6)
11bf3cce
LP
1202 in_addr.in6.s6_addr[15] |= 1;
1203
99b46669 1204 r = address_dup(original, &na);
cde1f0e8
YW
1205 if (r < 0)
1206 return r;
11bf3cce 1207
11bf3cce
LP
1208 na->in_addr = in_addr;
1209
1cc6c93a 1210 *ret = TAKE_PTR(na);
9684a8de 1211 return 0;
11bf3cce
LP
1212}
1213
5a07fa9d
YW
1214int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
1215 int r;
1216
1217 assert(rtnl);
1218 assert(m);
1219 assert(link);
1220 assert(error_msg);
1221
5a07fa9d
YW
1222 r = sd_netlink_message_get_errno(m);
1223 if (r < 0 && r != -EEXIST) {
1224 log_link_message_warning_errno(link, m, r, error_msg);
1225 link_enter_failed(link);
1226 return 0;
3a1dfdb4 1227 }
5a07fa9d
YW
1228
1229 return 1;
1230}
1231
b9e4ec50 1232static int address_configure(const Address *address, const struct ifa_cacheinfo *c, Link *link, Request *req) {
a79a8d16 1233 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
7b3a7581 1234 int r;
f579559b 1235
c166a070 1236 assert(address);
4c701096 1237 assert(IN_SET(address->family, AF_INET, AF_INET6));
b9e4ec50 1238 assert(c);
c166a070
TG
1239 assert(link);
1240 assert(link->ifindex > 0);
f882c247 1241 assert(link->manager);
c166a070 1242 assert(link->manager->rtnl);
54ff39f7 1243 assert(req);
f882c247 1244
c0c04a4b 1245 log_address_debug(address, "Configuring", link);
1b566071 1246
a79a8d16 1247 r = sd_rtnl_message_new_addr_update(link->manager->rtnl, &m, link->ifindex, address->family);
eb56eb9b 1248 if (r < 0)
a79a8d16 1249 return r;
f579559b 1250
a79a8d16 1251 r = address_set_netlink_message(address, m, link);
eb56eb9b 1252 if (r < 0)
a8481354 1253 return r;
851c9f82 1254
a79a8d16 1255 r = sd_rtnl_message_addr_set_scope(m, address->scope);
eb56eb9b 1256 if (r < 0)
a79a8d16 1257 return r;
5a723174 1258
94876904 1259 if (in_addr_is_set(address->family, &address->in_addr_peer)) {
a79a8d16 1260 r = netlink_message_append_in_addr_union(m, IFA_ADDRESS, address->family, &address->in_addr_peer);
eb56eb9b 1261 if (r < 0)
a79a8d16 1262 return r;
e680486d 1263 } else if (in4_addr_is_set(&address->broadcast)) {
a79a8d16 1264 r = sd_netlink_message_append_in_addr(m, IFA_BROADCAST, &address->broadcast);
66e0bb33 1265 if (r < 0)
a79a8d16 1266 return r;
f579559b
TG
1267 }
1268
2a236f9f 1269 if (address->family == AF_INET && address->label) {
a79a8d16 1270 r = sd_netlink_message_append_string(m, IFA_LABEL, address->label);
eb56eb9b 1271 if (r < 0)
a79a8d16 1272 return r;
f579559b
TG
1273 }
1274
b9e4ec50 1275 r = sd_netlink_message_append_cache_info(m, IFA_CACHEINFO, c);
eb56eb9b 1276 if (r < 0)
a79a8d16 1277 return r;
68ceb9df 1278
a79a8d16 1279 r = sd_netlink_message_append_u32(m, IFA_RT_PRIORITY, address->route_metric);
c4ff0629 1280 if (r < 0)
a79a8d16 1281 return r;
c4ff0629 1282
80d62d4f 1283 return request_call_netlink_async(link->manager->rtnl, m, req);
f579559b
TG
1284}
1285
8bed7c55
YW
1286static bool address_is_ready_to_configure(Link *link, const Address *address) {
1287 assert(link);
1288 assert(address);
1289
1290 if (!link_is_ready_to_configure(link, false))
1291 return false;
1292
5385e5f9 1293 if (!ipv4acd_bound(link, address))
8bed7c55
YW
1294 return false;
1295
1296 /* Refuse adding more than the limit */
1297 if (set_size(link->addresses) >= ADDRESSES_PER_LINK_MAX)
1298 return false;
1299
1300 return true;
1301}
1302
09d09207 1303static int address_process_request(Request *req, Link *link, Address *address) {
0a0c2672 1304 struct Address *existing;
b9e4ec50 1305 struct ifa_cacheinfo c;
8bed7c55
YW
1306 int r;
1307
1308 assert(req);
ff51134c
YW
1309 assert(link);
1310 assert(address);
8bed7c55
YW
1311
1312 if (!address_is_ready_to_configure(link, address))
1313 return 0;
1314
b9e4ec50
YW
1315 address_set_cinfo(link->manager, address, &c);
1316 if (c.ifa_valid == 0) {
1317 log_link_debug(link, "Refuse to configure %s address %s, as its valid lifetime is zero.",
1318 network_config_source_to_string(address->source),
1319 IN_ADDR_PREFIX_TO_STRING(address->family, &address->in_addr, address->prefixlen));
0a0c2672 1320
b9e4ec50 1321 address_cancel_requesting(address);
0a0c2672 1322 if (address_get(link, address, &existing) >= 0)
d6b64f7a 1323 address_cancel_requesting(existing);
b9e4ec50
YW
1324 return 1;
1325 }
1326
1327 r = address_configure(address, &c, link, req);
8bed7c55
YW
1328 if (r < 0)
1329 return log_link_warning_errno(link, r, "Failed to configure address: %m");
1330
1331 address_enter_configuring(address);
0a0c2672
YW
1332 if (address_get(link, address, &existing) >= 0)
1333 address_enter_configuring(existing);
1334
8bed7c55
YW
1335 return 1;
1336}
1337
76c5a0f2
YW
1338int link_request_address(
1339 Link *link,
f60e6558 1340 const Address *address,
76c5a0f2 1341 unsigned *message_counter,
80d62d4f 1342 address_netlink_handler_t netlink_handler,
76c5a0f2
YW
1343 Request **ret) {
1344
0a0c2672
YW
1345 _cleanup_(address_freep) Address *tmp = NULL;
1346 Address *existing = NULL;
c0c04a4b
YW
1347 int r;
1348
76c5a0f2
YW
1349 assert(link);
1350 assert(address);
3b6a3bde 1351 assert(address->source != NETWORK_CONFIG_SOURCE_FOREIGN);
76c5a0f2 1352
0a0c2672
YW
1353 if (address->lifetime_valid_usec == 0)
1354 /* The requested address is outdated. Let's ignore the request. */
1355 return 0;
af2aea8b 1356
0a0c2672
YW
1357 if (address_get(link, address, &existing) < 0) {
1358 if (address_get_request(link, address, NULL) >= 0)
1359 return 0; /* already requested, skipping. */
303dfa73 1360
9684a8de
YW
1361 r = address_acquire(link, address, &tmp);
1362 if (r < 0)
1363 return log_link_warning_errno(link, r, "Failed to acquire an address from pool: %m");
af2aea8b 1364
3b6a3bde
YW
1365 /* Consider address tentative until we get the real flags from the kernel */
1366 tmp->flags |= IFA_F_TENTATIVE;
1367
3b6a3bde 1368 } else {
0a0c2672 1369 r = address_dup(address, &tmp);
42f8b6a8 1370 if (r < 0)
0a0c2672 1371 return log_oom();
9684a8de 1372
0a0c2672
YW
1373 /* Copy already assigned address when it is requested as a null address. */
1374 if (address_is_static_null(address))
1375 tmp->in_addr = existing->in_addr;
9684a8de 1376
0a0c2672
YW
1377 /* Copy state for logging below. */
1378 tmp->state = existing->state;
c0c04a4b
YW
1379 }
1380
0a0c2672
YW
1381 address_set_broadcast(tmp, link);
1382
1383 r = ipv4acd_configure(link, tmp);
3b6a3bde
YW
1384 if (r < 0)
1385 return r;
1386
0a0c2672 1387 log_address_debug(tmp, "Requesting", link);
09d09207 1388 r = link_queue_request_safe(link, REQUEST_TYPE_ADDRESS,
0a0c2672
YW
1389 tmp,
1390 address_free,
0b8b30f6
YW
1391 address_kernel_hash_func,
1392 address_kernel_compare_func,
09d09207
YW
1393 address_process_request,
1394 message_counter, netlink_handler, ret);
c0c04a4b
YW
1395 if (r < 0)
1396 return log_link_warning_errno(link, r, "Failed to request address: %m");
3b6a3bde
YW
1397 if (r == 0)
1398 return 0;
1399
0a0c2672
YW
1400 address_enter_requesting(tmp);
1401 if (existing)
1402 address_enter_requesting(existing);
3b6a3bde 1403
0a0c2672 1404 TAKE_PTR(tmp);
3b6a3bde 1405 return 1;
76c5a0f2
YW
1406}
1407
80d62d4f 1408static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
e1e4cd1e
YW
1409 int r;
1410
1411 assert(link);
e1e4cd1e
YW
1412
1413 r = address_configure_handler_internal(rtnl, m, link, "Failed to set static address");
1414 if (r <= 0)
1415 return r;
1416
1417 if (link->static_address_messages == 0) {
1418 log_link_debug(link, "Addresses set");
1419 link->static_addresses_configured = true;
1420 link_check_ready(link);
1421 }
1422
1423 return 1;
1424}
1425
f60e6558 1426int link_request_static_address(Link *link, const Address *address) {
8c29f484
YW
1427 assert(link);
1428 assert(address);
3b6a3bde 1429 assert(address->source == NETWORK_CONFIG_SOURCE_STATIC);
8c29f484 1430
f60e6558 1431 return link_request_address(link, address, &link->static_address_messages,
3b6a3bde 1432 static_address_handler, NULL);
8c29f484
YW
1433}
1434
76c5a0f2
YW
1435int link_request_static_addresses(Link *link) {
1436 Address *a;
682c65b0
YW
1437 int r;
1438
1439 assert(link);
1440 assert(link->network);
1441
76c5a0f2 1442 link->static_addresses_configured = false;
682c65b0 1443
76c5a0f2 1444 ORDERED_HASHMAP_FOREACH(a, link->network->addresses_by_section) {
f60e6558 1445 r = link_request_static_address(link, a);
682c65b0
YW
1446 if (r < 0)
1447 return r;
1448 }
1449
3b6a3bde
YW
1450 r = link_request_radv_addresses(link);
1451 if (r < 0)
1452 return r;
0017ba31 1453
3b6a3bde
YW
1454 r = link_request_dhcp_server_address(link);
1455 if (r < 0)
1456 return r;
0017ba31 1457
76c5a0f2
YW
1458 if (link->static_address_messages == 0) {
1459 link->static_addresses_configured = true;
1460 link_check_ready(link);
682c65b0
YW
1461 } else {
1462 log_link_debug(link, "Setting addresses");
1463 link_set_state(link, LINK_STATE_CONFIGURING);
1464 }
1465
1466 return 0;
1467}
1468
e1e4cd1e
YW
1469void address_cancel_request(Address *address) {
1470 Request req;
1471
1472 assert(address);
1473 assert(address->link);
1474
1475 if (!address_is_requesting(address))
1476 return;
1477
1478 req = (Request) {
1479 .link = address->link,
1480 .type = REQUEST_TYPE_ADDRESS,
09d09207 1481 .userdata = address,
0b8b30f6
YW
1482 .hash_func = (hash_func_t) address_kernel_hash_func,
1483 .compare_func = (compare_func_t) address_kernel_compare_func,
e1e4cd1e
YW
1484 };
1485
e26d3d40 1486 request_detach(address->link->manager, &req);
e1e4cd1e
YW
1487 address_cancel_requesting(address);
1488}
1489
e1fc2c43 1490int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
fe841414 1491 _cleanup_(address_freep) Address *tmp = NULL;
16bc8635 1492 struct ifa_cacheinfo cinfo;
a3a25d01 1493 Link *link;
e1fc2c43 1494 uint16_t type;
e1fc2c43 1495 Address *address = NULL;
0a0c2672 1496 Request *req = NULL;
3c283289 1497 bool is_new = false;
fe841414 1498 int ifindex, r;
e1fc2c43
YW
1499
1500 assert(rtnl);
1501 assert(message);
1502 assert(m);
1503
1504 if (sd_netlink_message_is_error(message)) {
1505 r = sd_netlink_message_get_errno(message);
1506 if (r < 0)
1507 log_message_warning_errno(message, r, "rtnl: failed to receive address message, ignoring");
1508
1509 return 0;
1510 }
1511
1512 r = sd_netlink_message_get_type(message, &type);
1513 if (r < 0) {
1514 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
1515 return 0;
1516 } else if (!IN_SET(type, RTM_NEWADDR, RTM_DELADDR)) {
1517 log_warning("rtnl: received unexpected message type %u when processing address, ignoring.", type);
1518 return 0;
1519 }
1520
1521 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
1522 if (r < 0) {
1523 log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m");
1524 return 0;
1525 } else if (ifindex <= 0) {
1526 log_warning("rtnl: received address message with invalid ifindex %d, ignoring.", ifindex);
1527 return 0;
1528 }
1529
6eab614d 1530 r = link_get_by_index(m, ifindex, &link);
a3a25d01 1531 if (r < 0) {
e1fc2c43
YW
1532 /* when enumerating we might be out of sync, but we will get the address again, so just
1533 * ignore it */
1534 if (!m->enumerating)
1535 log_warning("rtnl: received address for link '%d' we don't know about, ignoring.", ifindex);
1536 return 0;
1537 }
1538
fe841414
YW
1539 r = address_new(&tmp);
1540 if (r < 0)
1541 return log_oom();
1542
3c283289
YW
1543 /* First, read minimal information to make address_get() work below. */
1544
fe841414 1545 r = sd_rtnl_message_addr_get_family(message, &tmp->family);
e1fc2c43
YW
1546 if (r < 0) {
1547 log_link_warning(link, "rtnl: received address message without family, ignoring.");
1548 return 0;
fe841414
YW
1549 } else if (!IN_SET(tmp->family, AF_INET, AF_INET6)) {
1550 log_link_debug(link, "rtnl: received address message with invalid family '%i', ignoring.", tmp->family);
e1fc2c43
YW
1551 return 0;
1552 }
1553
fe841414 1554 r = sd_rtnl_message_addr_get_prefixlen(message, &tmp->prefixlen);
e1fc2c43 1555 if (r < 0) {
9a0ad16b 1556 log_link_warning_errno(link, r, "rtnl: received address message without prefixlen, ignoring: %m");
e1fc2c43
YW
1557 return 0;
1558 }
1559
fe841414 1560 switch (tmp->family) {
e1fc2c43 1561 case AF_INET:
fe841414 1562 r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &tmp->in_addr.in);
e1fc2c43
YW
1563 if (r < 0) {
1564 log_link_warning_errno(link, r, "rtnl: received address message without valid address, ignoring: %m");
1565 return 0;
1566 }
1567
fe841414
YW
1568 r = sd_netlink_message_read_in_addr(message, IFA_ADDRESS, &tmp->in_addr_peer.in);
1569 if (r < 0 && r != -ENODATA) {
1570 log_link_warning_errno(link, r, "rtnl: could not get peer address from address message, ignoring: %m");
1571 return 0;
1572 } else if (r >= 0) {
1573 if (in4_addr_equal(&tmp->in_addr.in, &tmp->in_addr_peer.in))
1574 tmp->in_addr_peer = IN_ADDR_NULL;
fe841414
YW
1575 }
1576
e1fc2c43
YW
1577 break;
1578
1579 case AF_INET6:
fe841414
YW
1580 r = sd_netlink_message_read_in6_addr(message, IFA_LOCAL, &tmp->in_addr.in6);
1581 if (r >= 0) {
1582 /* Have peer address. */
1583 r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &tmp->in_addr_peer.in6);
1584 if (r < 0) {
1585 log_link_warning_errno(link, r, "rtnl: could not get peer address from address message, ignoring: %m");
1586 return 0;
1587 }
fe841414
YW
1588 } else if (r == -ENODATA) {
1589 /* Does not have peer address. */
1590 r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &tmp->in_addr.in6);
1591 if (r < 0) {
1592 log_link_warning_errno(link, r, "rtnl: received address message without valid address, ignoring: %m");
1593 return 0;
1594 }
1595 } else {
1596 log_link_warning_errno(link, r, "rtnl: could not get local address from address message, ignoring: %m");
e1fc2c43
YW
1597 return 0;
1598 }
1599
1600 break;
1601
1602 default:
04499a70 1603 assert_not_reached();
e1fc2c43
YW
1604 }
1605
0a0c2672 1606 /* Then, find the managed Address and Request objects corresponding to the received address. */
fe841414 1607 (void) address_get(link, tmp, &address);
0a0c2672 1608 (void) address_get_request(link, tmp, &req);
e1fc2c43 1609
3c283289 1610 if (type == RTM_DELADDR) {
3b6a3bde 1611 if (address) {
3c283289 1612 address_enter_removed(address);
0a0c2672 1613 log_address_debug(address, "Forgetting removed", link);
3c283289
YW
1614 (void) address_drop(address);
1615 } else
1616 log_address_debug(tmp, "Kernel removed unknown", link);
3b6a3bde 1617
0a0c2672
YW
1618 if (req)
1619 address_enter_removed(req->userdata);
1620
3c283289
YW
1621 return 0;
1622 }
3b6a3bde 1623
3c283289
YW
1624 if (!address) {
1625 /* If we did not know the address, then save it. */
1626 r = address_add(link, tmp);
1627 if (r < 0) {
1628 log_link_warning_errno(link, r, "Failed to remember foreign address %s, ignoring: %m",
1629 IN_ADDR_PREFIX_TO_STRING(tmp->family, &tmp->in_addr, tmp->prefixlen));
1630 return 0;
e1fc2c43 1631 }
3c283289 1632 address = TAKE_PTR(tmp);
e1fc2c43 1633
3c283289 1634 is_new = true;
e1fc2c43 1635
3c283289
YW
1636 } else {
1637 /* Otherwise, update the managed Address object with the netlink notification. */
1638 address->prefixlen = tmp->prefixlen;
1639 address->in_addr_peer = tmp->in_addr_peer;
1640 }
e1fc2c43 1641
0a0c2672
YW
1642 /* Also update information that cannot be obtained through netlink notification. */
1643 if (req && req->waiting_reply) {
1644 Address *a = ASSERT_PTR(req->userdata);
1645
1646 address->source = a->source;
1647 address->provider = a->provider;
1648 (void) free_and_strdup_warn(&address->netlabel, a->netlabel);
1649 address->requested_as_null = a->requested_as_null;
1650 address->callback = a->callback;
1651 }
1652
3c283289
YW
1653 /* Then, update miscellaneous info. */
1654 r = sd_rtnl_message_addr_get_scope(message, &address->scope);
1655 if (r < 0)
1656 log_link_debug_errno(link, r, "rtnl: received address message without scope, ignoring: %m");
e1fc2c43 1657
3c283289
YW
1658 if (address->family == AF_INET) {
1659 _cleanup_free_ char *label = NULL;
e1fc2c43 1660
3c283289
YW
1661 r = sd_netlink_message_read_string_strdup(message, IFA_LABEL, &label);
1662 if (r >= 0) {
1663 if (!streq_ptr(label, link->ifname))
1664 free_and_replace(address->label, label);
1665 } else if (r != -ENODATA)
1666 log_link_debug_errno(link, r, "rtnl: could not get label from address message, ignoring: %m");
1667
1668 r = sd_netlink_message_read_in_addr(message, IFA_BROADCAST, &address->broadcast);
1669 if (r < 0 && r != -ENODATA)
1670 log_link_debug_errno(link, r, "rtnl: could not get broadcast from address message, ignoring: %m");
e1fc2c43
YW
1671 }
1672
3c283289
YW
1673 r = sd_netlink_message_read_u32(message, IFA_FLAGS, &address->flags);
1674 if (r == -ENODATA) {
1675 unsigned char flags;
1676
1677 /* For old kernels. */
1678 r = sd_rtnl_message_addr_get_flags(message, &flags);
1679 if (r >= 0)
1680 address->flags = flags;
1681 } else if (r < 0)
1682 log_link_debug_errno(link, r, "rtnl: failed to read IFA_FLAGS attribute, ignoring: %m");
1683
1684 r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo);
1685 if (r >= 0)
1686 address_set_lifetime(m, address, &cinfo);
1687 else if (r != -ENODATA)
1688 log_link_debug_errno(link, r, "rtnl: failed to read IFA_CACHEINFO attribute, ignoring: %m");
1689
7e18f9b4
YW
1690 r = sd_netlink_message_read_u32(message, IFA_RT_PRIORITY, &address->route_metric);
1691 if (r < 0 && r != -ENODATA)
1692 log_link_debug_errno(link, r, "rtnl: failed to read IFA_RT_PRIORITY attribute, ignoring: %m");
1693
3c283289 1694 address_enter_configured(address);
0a0c2672
YW
1695 if (req)
1696 address_enter_configured(req->userdata);
1697
3c283289
YW
1698 log_address_debug(address, is_new ? "Received new": "Received updated", link);
1699
1700 /* address_update() logs internally, so we don't need to here. */
1701 r = address_update(address);
1702 if (r < 0)
1703 link_enter_failed(link);
1704
e1fc2c43
YW
1705 return 1;
1706}
1707
44e7b949
LP
1708int config_parse_broadcast(
1709 const char *unit,
eb0ea358
TG
1710 const char *filename,
1711 unsigned line,
1712 const char *section,
1713 unsigned section_line,
1714 const char *lvalue,
1715 int ltype,
1716 const char *rvalue,
1717 void *data,
1718 void *userdata) {
44e7b949 1719
eb0ea358 1720 Network *network = userdata;
fcbf4cb7 1721 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
94af46fc 1722 union in_addr_union u;
eb0ea358
TG
1723 int r;
1724
1725 assert(filename);
1726 assert(section);
1727 assert(lvalue);
1728 assert(rvalue);
1729 assert(data);
1730
f4859fc7 1731 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1732 if (r == -ENOMEM)
1733 return log_oom();
1734 if (r < 0) {
1735 log_syntax(unit, LOG_WARNING, filename, line, r,
1736 "Failed to allocate new address, ignoring assignment: %m");
1737 return 0;
1738 }
eb0ea358 1739
832583ad
YW
1740 if (isempty(rvalue)) {
1741 /* The broadcast address will be calculated based on Address=, and set if the link is
1742 * not a wireguard interface. Here, we do not check or set n->family. */
1743 n->broadcast = (struct in_addr) {};
1744 n->set_broadcast = -1;
1745 TAKE_PTR(n);
1746 return 0;
1747 }
1748
1749 r = parse_boolean(rvalue);
1750 if (r >= 0) {
1751 /* The broadcast address will be calculated based on Address=. Here, we do not check or
1752 * set n->family. */
1753 n->broadcast = (struct in_addr) {};
1754 n->set_broadcast = r;
1755 TAKE_PTR(n);
1756 return 0;
1757 }
1758
482e2ac1 1759 if (n->family == AF_INET6) {
d96edb2c 1760 log_syntax(unit, LOG_WARNING, filename, line, 0,
2850cd40 1761 "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue);
482e2ac1
TG
1762 return 0;
1763 }
1764
94af46fc 1765 r = in_addr_from_string(AF_INET, rvalue, &u);
eb0ea358 1766 if (r < 0) {
d96edb2c 1767 log_syntax(unit, LOG_WARNING, filename, line, r,
2850cd40 1768 "Broadcast is invalid, ignoring assignment: %s", rvalue);
eb0ea358
TG
1769 return 0;
1770 }
832583ad
YW
1771 if (in4_addr_is_null(&u.in)) {
1772 log_syntax(unit, LOG_WARNING, filename, line, 0,
1773 "Broadcast cannot be ANY address, ignoring assignment: %s", rvalue);
1774 return 0;
1775 }
eb0ea358 1776
94af46fc 1777 n->broadcast = u.in;
832583ad 1778 n->set_broadcast = true;
44e7b949 1779 n->family = AF_INET;
dea161d9 1780 TAKE_PTR(n);
eb0ea358
TG
1781
1782 return 0;
1783}
1784
f5ee7d74
YW
1785int config_parse_address(
1786 const char *unit,
f579559b
TG
1787 const char *filename,
1788 unsigned line,
1789 const char *section,
71a61510 1790 unsigned section_line,
f579559b
TG
1791 const char *lvalue,
1792 int ltype,
1793 const char *rvalue,
1794 void *data,
1795 void *userdata) {
44e7b949 1796
6ae115c1 1797 Network *network = userdata;
fcbf4cb7 1798 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
44e7b949 1799 union in_addr_union buffer;
b7cb4452 1800 unsigned char prefixlen;
44e7b949 1801 int r, f;
f579559b
TG
1802
1803 assert(filename);
6ae115c1 1804 assert(section);
f579559b
TG
1805 assert(lvalue);
1806 assert(rvalue);
1807 assert(data);
1808
9cd9fc8f
YW
1809 if (streq(section, "Network"))
1810 /* we are not in an Address section, so use line number instead. */
1811 r = address_new_static(network, filename, line, &n);
1812 else
f4859fc7 1813 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1814 if (r == -ENOMEM)
1815 return log_oom();
1816 if (r < 0) {
1817 log_syntax(unit, LOG_WARNING, filename, line, r,
1818 "Failed to allocate new address, ignoring assignment: %m");
1819 return 0;
1820 }
f579559b
TG
1821
1822 /* Address=address/prefixlen */
0f707207
YW
1823 r = in_addr_prefix_from_string_auto_internal(rvalue, PREFIXLEN_REFUSE, &f, &buffer, &prefixlen);
1824 if (r == -ENOANO) {
e5e07431
YW
1825 r = in_addr_prefix_from_string_auto(rvalue, &f, &buffer, &prefixlen);
1826 if (r >= 0)
1827 log_syntax(unit, LOG_WARNING, filename, line, r,
497cee30 1828 "Address '%s' is specified without prefix length. Assuming the prefix length is %u."
e5e07431 1829 "Please specify the prefix length explicitly.", rvalue, prefixlen);
0f707207 1830 }
f579559b 1831 if (r < 0) {
d96edb2c 1832 log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid address '%s', ignoring assignment: %m", rvalue);
f579559b
TG
1833 return 0;
1834 }
1835
44e7b949 1836 if (n->family != AF_UNSPEC && f != n->family) {
d96edb2c 1837 log_syntax(unit, LOG_WARNING, filename, line, 0, "Address is incompatible, ignoring assignment: %s", rvalue);
44e7b949
LP
1838 return 0;
1839 }
1840
c9207ff3
YW
1841 if (in_addr_is_null(f, &buffer)) {
1842 /* Will use address from address pool. Note that for ipv6 case, prefix of the address
1843 * pool is 8, but 40 bit is used by the global ID and 16 bit by the subnet ID. So,
1844 * let's limit the prefix length to 64 or larger. See RFC4193. */
1845 if ((f == AF_INET && prefixlen < 8) ||
1846 (f == AF_INET6 && prefixlen < 64)) {
d96edb2c 1847 log_syntax(unit, LOG_WARNING, filename, line, 0,
c9207ff3
YW
1848 "Null address with invalid prefixlen='%u', ignoring assignment: %s",
1849 prefixlen, rvalue);
1850 return 0;
1851 }
1852 }
1853
44e7b949 1854 n->family = f;
b7cb4452 1855 n->prefixlen = prefixlen;
44e7b949 1856
d0009d92 1857 if (streq(lvalue, "Address")) {
44e7b949 1858 n->in_addr = buffer;
d0009d92
YW
1859 n->requested_as_null = !in_addr_is_set(n->family, &n->in_addr);
1860 } else
44e7b949
LP
1861 n->in_addr_peer = buffer;
1862
dea161d9 1863 TAKE_PTR(n);
f579559b
TG
1864 return 0;
1865}
6ae115c1 1866
d31645ad
LP
1867int config_parse_label(
1868 const char *unit,
6ae115c1
TG
1869 const char *filename,
1870 unsigned line,
1871 const char *section,
1872 unsigned section_line,
1873 const char *lvalue,
1874 int ltype,
1875 const char *rvalue,
1876 void *data,
1877 void *userdata) {
d31645ad 1878
fcbf4cb7 1879 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
d31645ad 1880 Network *network = userdata;
6ae115c1
TG
1881 int r;
1882
1883 assert(filename);
1884 assert(section);
1885 assert(lvalue);
1886 assert(rvalue);
1887 assert(data);
1888
f4859fc7 1889 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1890 if (r == -ENOMEM)
1891 return log_oom();
1892 if (r < 0) {
1893 log_syntax(unit, LOG_WARNING, filename, line, r,
1894 "Failed to allocate new address, ignoring assignment: %m");
1895 return 0;
1896 }
6ae115c1 1897
a87d19fe 1898 if (!address_label_valid(rvalue)) {
d96edb2c 1899 log_syntax(unit, LOG_WARNING, filename, line, 0,
2850cd40 1900 "Interface label is too long or invalid, ignoring assignment: %s", rvalue);
6ae115c1
TG
1901 return 0;
1902 }
1903
d31645ad
LP
1904 r = free_and_strdup(&n->label, rvalue);
1905 if (r < 0)
1906 return log_oom();
6ae115c1 1907
dea161d9 1908 TAKE_PTR(n);
6ae115c1
TG
1909 return 0;
1910}
ce6c77eb 1911
f5ee7d74
YW
1912int config_parse_lifetime(
1913 const char *unit,
1914 const char *filename,
1915 unsigned line,
1916 const char *section,
1917 unsigned section_line,
1918 const char *lvalue,
1919 int ltype,
1920 const char *rvalue,
1921 void *data,
1922 void *userdata) {
1923
b5834a0b 1924 Network *network = userdata;
fcbf4cb7 1925 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
16bc8635 1926 usec_t k;
b5834a0b
SS
1927 int r;
1928
1929 assert(filename);
1930 assert(section);
1931 assert(lvalue);
1932 assert(rvalue);
1933 assert(data);
1934
f4859fc7 1935 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1936 if (r == -ENOMEM)
1937 return log_oom();
1938 if (r < 0) {
1939 log_syntax(unit, LOG_WARNING, filename, line, r,
1940 "Failed to allocate new address, ignoring assignment: %m");
1941 return 0;
1942 }
b5834a0b 1943
10b20e5a
ZJS
1944 /* We accept only "forever", "infinity", empty, or "0". */
1945 if (STR_IN_SET(rvalue, "forever", "infinity", ""))
16bc8635 1946 k = USEC_INFINITY;
33680b0a
YW
1947 else if (streq(rvalue, "0"))
1948 k = 0;
1949 else {
d96edb2c 1950 log_syntax(unit, LOG_WARNING, filename, line, 0,
33680b0a 1951 "Invalid PreferredLifetime= value, ignoring: %s", rvalue);
b5834a0b
SS
1952 return 0;
1953 }
1954
16bc8635 1955 n->lifetime_preferred_usec = k;
d2735796 1956 TAKE_PTR(n);
b5834a0b
SS
1957
1958 return 0;
1959}
1960
f5ee7d74
YW
1961int config_parse_address_flags(
1962 const char *unit,
1963 const char *filename,
1964 unsigned line,
1965 const char *section,
1966 unsigned section_line,
1967 const char *lvalue,
1968 int ltype,
1969 const char *rvalue,
1970 void *data,
1971 void *userdata) {
1972
e63be084 1973 Network *network = userdata;
fcbf4cb7 1974 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
e63be084
SS
1975 int r;
1976
1977 assert(filename);
1978 assert(section);
1979 assert(lvalue);
1980 assert(rvalue);
1981 assert(data);
1982
f4859fc7 1983 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
1984 if (r == -ENOMEM)
1985 return log_oom();
1986 if (r < 0) {
1987 log_syntax(unit, LOG_WARNING, filename, line, r,
1988 "Failed to allocate new address, ignoring assignment: %m");
1989 return 0;
1990 }
e63be084
SS
1991
1992 r = parse_boolean(rvalue);
1993 if (r < 0) {
d96edb2c 1994 log_syntax(unit, LOG_WARNING, filename, line, r,
051e77ca 1995 "Failed to parse %s=, ignoring: %s", lvalue, rvalue);
e63be084
SS
1996 return 0;
1997 }
1998
eaff204f
YW
1999 if (streq(lvalue, "AddPrefixRoute"))
2000 r = !r;
2001
2002 SET_FLAG(n->flags, ltype, r);
e63be084 2003
dea161d9 2004 TAKE_PTR(n);
e63be084
SS
2005 return 0;
2006}
2007
f5ee7d74
YW
2008int config_parse_address_scope(
2009 const char *unit,
2010 const char *filename,
2011 unsigned line,
2012 const char *section,
2013 unsigned section_line,
2014 const char *lvalue,
2015 int ltype,
2016 const char *rvalue,
2017 void *data,
2018 void *userdata) {
2019
2959fb07 2020 Network *network = userdata;
fcbf4cb7 2021 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
2959fb07
SS
2022 int r;
2023
2024 assert(filename);
2025 assert(section);
2026 assert(lvalue);
2027 assert(rvalue);
2028 assert(data);
2029
2030 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
2031 if (r == -ENOMEM)
2032 return log_oom();
2033 if (r < 0) {
2034 log_syntax(unit, LOG_WARNING, filename, line, r,
2035 "Failed to allocate new address, ignoring assignment: %m");
2036 return 0;
2037 }
2959fb07 2038
d8c472f2
YW
2039 r = route_scope_from_string(rvalue);
2040 if (r < 0) {
2041 log_syntax(unit, LOG_WARNING, filename, line, r,
2042 "Could not parse address scope \"%s\", ignoring assignment: %m", rvalue);
2043 return 0;
2959fb07
SS
2044 }
2045
d8c472f2 2046 n->scope = r;
07336a06 2047 n->scope_set = true;
dea161d9 2048 TAKE_PTR(n);
2959fb07
SS
2049 return 0;
2050}
2051
c4ff0629
YW
2052int config_parse_address_route_metric(
2053 const char *unit,
2054 const char *filename,
2055 unsigned line,
2056 const char *section,
2057 unsigned section_line,
2058 const char *lvalue,
2059 int ltype,
2060 const char *rvalue,
2061 void *data,
2062 void *userdata) {
2063
2064 Network *network = userdata;
2065 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
2066 int r;
2067
2068 assert(filename);
2069 assert(section);
2070 assert(lvalue);
2071 assert(rvalue);
2072 assert(data);
2073
2074 r = address_new_static(network, filename, section_line, &n);
2075 if (r == -ENOMEM)
2076 return log_oom();
2077 if (r < 0) {
2078 log_syntax(unit, LOG_WARNING, filename, line, r,
2079 "Failed to allocate new address, ignoring assignment: %m");
2080 return 0;
2081 }
2082
2083 r = safe_atou32(rvalue, &n->route_metric);
2084 if (r < 0) {
2085 log_syntax(unit, LOG_WARNING, filename, line, r,
2086 "Could not parse %s=, ignoring assignment: %s", lvalue, rvalue);
2087 return 0;
2088 }
2089
2090 TAKE_PTR(n);
2091 return 0;
2092}
2093
051e77ca
SS
2094int config_parse_duplicate_address_detection(
2095 const char *unit,
2096 const char *filename,
2097 unsigned line,
2098 const char *section,
2099 unsigned section_line,
2100 const char *lvalue,
2101 int ltype,
2102 const char *rvalue,
2103 void *data,
2104 void *userdata) {
f5ee7d74 2105
051e77ca
SS
2106 Network *network = userdata;
2107 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
051e77ca
SS
2108 int r;
2109
2110 assert(filename);
2111 assert(section);
2112 assert(lvalue);
2113 assert(rvalue);
2114 assert(data);
2115
2116 r = address_new_static(network, filename, section_line, &n);
d96edb2c
YW
2117 if (r == -ENOMEM)
2118 return log_oom();
2119 if (r < 0) {
2120 log_syntax(unit, LOG_WARNING, filename, line, r,
2121 "Failed to allocate new address, ignoring assignment: %m");
2122 return 0;
2123 }
051e77ca
SS
2124
2125 r = parse_boolean(rvalue);
2126 if (r >= 0) {
2127 log_syntax(unit, LOG_WARNING, filename, line, 0,
2128 "For historical reasons, %s=%s means %s=%s. "
2129 "Please use 'both', 'ipv4', 'ipv6' or 'none' instead.",
2130 lvalue, rvalue, lvalue, r ? "none" : "both");
2131 n->duplicate_address_detection = r ? ADDRESS_FAMILY_NO : ADDRESS_FAMILY_YES;
2132 n = NULL;
2133 return 0;
2134 }
2135
7211c853 2136 AddressFamily a = duplicate_address_detection_address_family_from_string(rvalue);
051e77ca 2137 if (a < 0) {
7211c853 2138 log_syntax(unit, LOG_WARNING, filename, line, a,
051e77ca
SS
2139 "Failed to parse %s=, ignoring: %s", lvalue, rvalue);
2140 return 0;
2141 }
051e77ca 2142 n->duplicate_address_detection = a;
7211c853 2143
dea161d9 2144 TAKE_PTR(n);
051e77ca
SS
2145 return 0;
2146}
2147
4b3590c3
TM
2148int config_parse_address_netlabel(
2149 const char *unit,
2150 const char *filename,
2151 unsigned line,
2152 const char *section,
2153 unsigned section_line,
2154 const char *lvalue,
2155 int ltype,
2156 const char *rvalue,
2157 void *data,
2158 void *userdata) {
2159
2160 Network *network = userdata;
2161 _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
2162 int r;
2163
2164 assert(filename);
2165 assert(section);
2166 assert(lvalue);
2167 assert(rvalue);
2168 assert(data);
2169 assert(network);
2170
2171 r = address_new_static(network, filename, section_line, &n);
2172 if (r == -ENOMEM)
2173 return log_oom();
2174 if (r < 0) {
2175 log_syntax(unit, LOG_WARNING, filename, line, r,
2176 "Failed to allocate new address, ignoring assignment: %m");
2177 return 0;
2178 }
2179
2180 r = config_parse_string(unit, filename, line, section, section_line,
2181 lvalue, CONFIG_PARSE_STRING_SAFE, rvalue, &n->netlabel, network);
2182 if (r < 0)
2183 return r;
2184
2185 TAKE_PTR(n);
2186 return 0;
2187}
2188
9a45125a
YW
2189static void address_section_adjust_broadcast(Address *address) {
2190 assert(address);
2191 assert(address->section);
2192
2193 if (!in4_addr_is_set(&address->broadcast))
2194 return;
2195
2196 if (address->family == AF_INET6)
2197 log_warning("%s: broadcast address is set for an IPv6 address. "
2198 "Ignoring Broadcast= setting in the [Address] section from line %u.",
2199 address->section->filename, address->section->line);
2200 else if (address->prefixlen > 30)
2201 log_warning("%s: broadcast address is set for an IPv4 address with prefix length larger than 30. "
2202 "Ignoring Broadcast= setting in the [Address] section from line %u.",
2203 address->section->filename, address->section->line);
2204 else if (in4_addr_is_set(&address->in_addr_peer.in))
2205 log_warning("%s: broadcast address is set for an IPv4 address with peer address. "
2206 "Ignoring Broadcast= setting in the [Address] section from line %u.",
2207 address->section->filename, address->section->line);
0acc6470
YW
2208 else if (!in4_addr_is_set(&address->in_addr.in))
2209 log_warning("%s: broadcast address is set for an IPv4 address with null address. "
2210 "Ignoring Broadcast= setting in the [Address] section from line %u.",
2211 address->section->filename, address->section->line);
9a45125a
YW
2212 else
2213 /* Otherwise, keep the specified broadcast address. */
2214 return;
2215
2216 address->broadcast.s_addr = 0;
2217}
2218
32400c2f 2219static int address_section_verify(Address *address) {
fcbf4cb7
YW
2220 if (section_is_invalid(address->section))
2221 return -EINVAL;
2222
2223 if (address->family == AF_UNSPEC) {
2224 assert(address->section);
2225
2226 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
d9e2afc0 2227 "%s: Address section without Address= field was configured. "
fcbf4cb7
YW
2228 "Ignoring [Address] section from line %u.",
2229 address->section->filename, address->section->line);
2230 }
2231
d9e2afc0
YW
2232 if (address->family == AF_INET6 && !socket_ipv6_is_supported())
2233 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
2234 "%s: an IPv6 address was configured, but the kernel does not support IPv6. "
2235 "Ignoring [Address] section from line %u.",
2236 address->section->filename, address->section->line);
2237
2859932b
YW
2238 assert(IN_SET(address->family, AF_INET, AF_INET6));
2239
9a45125a 2240 address_section_adjust_broadcast(address);
fe841414
YW
2241
2242 if (address->family == AF_INET6 && address->label) {
2243 log_warning("%s: address label is set for IPv6 address in the [Address] section from line %u. "
2244 "Ignoring Label= setting.",
2245 address->section->filename, address->section->line);
2246
2247 address->label = mfree(address->label);
2248 }
2249
20228b6d
YW
2250 if (!address->scope_set) {
2251 if (in_addr_is_localhost(address->family, &address->in_addr) > 0)
2252 address->scope = RT_SCOPE_HOST;
2253 else if (in_addr_is_link_local(address->family, &address->in_addr) > 0)
2254 address->scope = RT_SCOPE_LINK;
2255 }
07336a06 2256
2859932b
YW
2257 if (address->duplicate_address_detection < 0) {
2258 if (address->family == AF_INET6)
2259 address->duplicate_address_detection = ADDRESS_FAMILY_IPV6;
2260 else if (in4_addr_is_link_local(&address->in_addr.in))
2261 address->duplicate_address_detection = ADDRESS_FAMILY_IPV4;
2262 else
2263 address->duplicate_address_detection = ADDRESS_FAMILY_NO;
2264 } else if (address->duplicate_address_detection == ADDRESS_FAMILY_IPV6 && address->family == AF_INET)
2265 log_warning("%s: DuplicateAddressDetection=ipv6 is specified for IPv4 address, ignoring.",
2266 address->section->filename);
2267 else if (address->duplicate_address_detection == ADDRESS_FAMILY_IPV4 && address->family == AF_INET6)
2268 log_warning("%s: DuplicateAddressDetection=ipv4 is specified for IPv6 address, ignoring.",
2269 address->section->filename);
2270
bd5146c6
YW
2271 if (address->family == AF_INET6 &&
2272 !FLAGS_SET(address->duplicate_address_detection, ADDRESS_FAMILY_IPV6))
eaff204f
YW
2273 address->flags |= IFA_F_NODAD;
2274
b1179a5d
YW
2275 uint32_t filtered_flags = address->family == AF_INET ?
2276 address->flags & KNOWN_FLAGS & ~UNMANAGED_FLAGS & ~IPV6ONLY_FLAGS :
2277 address->flags & KNOWN_FLAGS & ~UNMANAGED_FLAGS;
2278 if (address->flags != filtered_flags) {
2279 _cleanup_free_ char *str = NULL;
2280
2281 (void) address_flags_to_string_alloc(filtered_flags, address->family, &str);
2282 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
2283 "%s: unexpected address flags \"%s\" were configured. "
2284 "Ignoring [Address] section from line %u.",
2285 address->section->filename, strna(str), address->section->line);
2286 }
2287
fcbf4cb7
YW
2288 return 0;
2289}
32400c2f 2290
50783f91
YW
2291int network_drop_invalid_addresses(Network *network) {
2292 _cleanup_set_free_ Set *addresses = NULL;
9cd9fc8f 2293 Address *address;
50783f91 2294 int r;
32400c2f
YW
2295
2296 assert(network);
2297
50783f91
YW
2298 ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section) {
2299 Address *dup;
2300
2301 if (address_section_verify(address) < 0) {
2302 /* Drop invalid [Address] sections or Address= settings in [Network].
2303 * Note that address_free() will drop the address from addresses_by_section. */
32400c2f 2304 address_free(address);
50783f91
YW
2305 continue;
2306 }
2307
2308 /* Always use the setting specified later. So, remove the previously assigned setting. */
2309 dup = set_remove(addresses, address);
2310 if (dup) {
50783f91
YW
2311 log_warning("%s: Duplicated address %s is specified at line %u and %u, "
2312 "dropping the address setting specified at line %u.",
c71384a9
ZJS
2313 dup->section->filename,
2314 IN_ADDR_PREFIX_TO_STRING(address->family, &address->in_addr, address->prefixlen),
2315 address->section->line,
50783f91
YW
2316 dup->section->line, dup->section->line);
2317 /* address_free() will drop the address from addresses_by_section. */
2318 address_free(dup);
2319 }
2320
42f8b6a8
YW
2321 /* Use address_kernel_hash_ops, instead of address_kernel_hash_ops_free. Otherwise, the
2322 * Address objects will be freed. */
5d003031 2323 r = set_ensure_put(&addresses, &address_kernel_hash_ops, address);
50783f91
YW
2324 if (r < 0)
2325 return log_oom();
2326 assert(r > 0);
2327 }
2328
2329 return 0;
32400c2f 2330}