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