1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <net/if_arp.h>
6 #include "alloc-util.h"
7 #include "firewall-util.h"
9 #include "memory-util.h"
10 #include "netlink-util.h"
11 #include "networkd-address-pool.h"
12 #include "networkd-address.h"
13 #include "networkd-dhcp-server.h"
14 #include "networkd-ipv4acd.h"
15 #include "networkd-manager.h"
16 #include "networkd-netlabel.h"
17 #include "networkd-network.h"
18 #include "networkd-queue.h"
19 #include "networkd-route-util.h"
20 #include "networkd-route.h"
21 #include "parse-util.h"
22 #include "string-util.h"
26 #define ADDRESSES_PER_LINK_MAX 2048U
27 #define STATIC_ADDRESSES_PER_NETWORK_MAX 1024U
38 IFA_F_MANAGETEMPADDR | \
39 IFA_F_NOPREFIXROUTE | \
43 /* From net/ipv4/devinet.c */
44 #define IPV6ONLY_FLAGS \
50 IFA_F_MANAGETEMPADDR | \
53 /* We do not control the following flags. */
54 #define UNMANAGED_FLAGS \
62 int address_flags_to_string_alloc(uint32_t flags
, int family
, char **ret
) {
63 _cleanup_free_
char *str
= NULL
;
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",
79 assert(IN_SET(family
, AF_INET
, AF_INET6
));
82 for (size_t i
= 0; i
< ELEMENTSOF(map
); i
++)
83 if (FLAGS_SET(flags
, 1 << i
) && map
[i
])
84 if (!strextend_with_separator(
86 family
== AF_INET6
&& (1 << i
) == IFA_F_SECONDARY
? "temporary" : map
[i
]))
93 int address_new(Address
**ret
) {
94 _cleanup_(address_freep
) Address
*address
= NULL
;
96 address
= new(Address
, 1);
100 *address
= (Address
) {
102 .scope
= RT_SCOPE_UNIVERSE
,
103 .lifetime_valid_usec
= USEC_INFINITY
,
104 .lifetime_preferred_usec
= USEC_INFINITY
,
108 *ret
= TAKE_PTR(address
);
113 int address_new_static(Network
*network
, const char *filename
, unsigned section_line
, Address
**ret
) {
114 _cleanup_(config_section_freep
) ConfigSection
*n
= NULL
;
115 _cleanup_(address_freep
) Address
*address
= NULL
;
121 assert(section_line
> 0);
123 r
= config_section_new(filename
, section_line
, &n
);
127 address
= ordered_hashmap_get(network
->addresses_by_section
, n
);
129 *ret
= TAKE_PTR(address
);
133 if (ordered_hashmap_size(network
->addresses_by_section
) >= STATIC_ADDRESSES_PER_NETWORK_MAX
)
136 r
= address_new(&address
);
140 address
->network
= network
;
141 address
->section
= TAKE_PTR(n
);
142 address
->source
= NETWORK_CONFIG_SOURCE_STATIC
;
143 /* This will be adjusted in address_section_verify(). */
144 address
->duplicate_address_detection
= _ADDRESS_FAMILY_INVALID
;
146 r
= ordered_hashmap_ensure_put(&network
->addresses_by_section
, &config_section_hash_ops
, address
->section
, address
);
150 *ret
= TAKE_PTR(address
);
154 Address
*address_free(Address
*address
) {
158 if (address
->network
) {
159 assert(address
->section
);
160 ordered_hashmap_remove(address
->network
->addresses_by_section
, address
->section
);
164 set_remove(address
->link
->addresses
, address
);
166 if (address
->family
== AF_INET6
&&
167 in6_addr_equal(&address
->in_addr
.in6
, &address
->link
->ipv6ll_address
))
168 memzero(&address
->link
->ipv6ll_address
, sizeof(struct in6_addr
));
170 ipv4acd_detach(address
->link
, address
);
173 config_section_free(address
->section
);
174 free(address
->label
);
175 free(address
->netlabel
);
176 nft_set_context_clear(&address
->nft_set_context
);
177 return mfree(address
);
180 static bool address_lifetime_is_valid(const Address
*a
) {
184 a
->lifetime_valid_usec
== USEC_INFINITY
||
185 a
->lifetime_valid_usec
> now(CLOCK_BOOTTIME
);
188 bool address_is_ready(const Address
*a
) {
192 if (!ipv4acd_bound(a
->link
, a
))
195 if (FLAGS_SET(a
->flags
, IFA_F_TENTATIVE
))
198 if (FLAGS_SET(a
->state
, NETWORK_CONFIG_STATE_REMOVING
))
201 if (!FLAGS_SET(a
->state
, NETWORK_CONFIG_STATE_CONFIGURED
))
204 return address_lifetime_is_valid(a
);
207 bool link_check_addresses_ready(Link
*link
, NetworkConfigSource source
) {
213 /* Check if all addresses on the interface are ready. If there is no address, this will return false. */
215 SET_FOREACH(a
, link
->addresses
) {
216 if (source
>= 0 && a
->source
!= source
)
218 if (address_is_marked(a
))
220 if (!address_exists(a
))
222 if (!address_is_ready(a
))
230 void link_mark_addresses(Link
*link
, NetworkConfigSource source
) {
235 SET_FOREACH(a
, link
->addresses
) {
236 if (a
->source
!= source
)
243 static int address_get_broadcast(const Address
*a
, Link
*link
, struct in_addr
*ret
) {
244 struct in_addr b_addr
= {};
249 /* Returns 0 when broadcast address is null, 1 when non-null broadcast address, -EAGAIN when the main
250 * address is null. */
252 /* broadcast is only for IPv4. */
253 if (a
->family
!= AF_INET
)
256 /* broadcast address cannot be used when peer address is specified. */
257 if (in4_addr_is_set(&a
->in_addr_peer
.in
))
260 /* A /31 or /32 IPv4 address does not have a broadcast address.
261 * See https://tools.ietf.org/html/rfc3021 */
262 if (a
->prefixlen
> 30)
265 /* If explicitly configured, use the address as is. */
266 if (in4_addr_is_set(&a
->broadcast
)) {
267 b_addr
= a
->broadcast
;
271 /* If explicitly disabled, then return null address. */
272 if (a
->set_broadcast
== 0)
275 /* For wireguard interfaces, broadcast is disabled by default. */
276 if (a
->set_broadcast
< 0 && streq_ptr(link
->kind
, "wireguard"))
279 /* If the main address is null, e.g. Address=0.0.0.0/24, the broadcast address will be automatically
280 * determined after an address is acquired. */
281 if (!in4_addr_is_set(&a
->in_addr
.in
))
284 /* Otherwise, generate a broadcast address from the main address and prefix length. */
285 b_addr
.s_addr
= a
->in_addr
.in
.s_addr
| htobe32(UINT32_C(0xffffffff) >> a
->prefixlen
);
291 return in4_addr_is_set(&b_addr
);
294 static void address_set_broadcast(Address
*a
, Link
*link
) {
296 assert_se(address_get_broadcast(a
, link
, &a
->broadcast
) >= 0);
299 static void address_set_cinfo(Manager
*m
, const Address
*a
, struct ifa_cacheinfo
*cinfo
) {
306 assert_se(sd_event_now(m
->event
, CLOCK_BOOTTIME
, &now_usec
) >= 0);
308 *cinfo
= (struct ifa_cacheinfo
) {
309 .ifa_valid
= usec_to_sec(a
->lifetime_valid_usec
, now_usec
),
310 .ifa_prefered
= usec_to_sec(a
->lifetime_preferred_usec
, now_usec
),
314 static void address_set_lifetime(Manager
*m
, Address
*a
, const struct ifa_cacheinfo
*cinfo
) {
321 assert_se(sd_event_now(m
->event
, CLOCK_BOOTTIME
, &now_usec
) >= 0);
323 a
->lifetime_valid_usec
= sec_to_usec(cinfo
->ifa_valid
, now_usec
);
324 a
->lifetime_preferred_usec
= sec_to_usec(cinfo
->ifa_prefered
, now_usec
);
327 static bool address_is_static_null(const Address
*address
) {
330 if (!address
->network
)
333 if (!address
->requested_as_null
)
336 assert(!in_addr_is_set(address
->family
, &address
->in_addr
));
340 static int address_ipv4_prefix(const Address
*a
, struct in_addr
*ret
) {
345 assert(a
->family
== AF_INET
);
348 p
= in4_addr_is_set(&a
->in_addr_peer
.in
) ? a
->in_addr_peer
.in
: a
->in_addr
.in
;
349 r
= in4_addr_mask(&p
, a
->prefixlen
);
357 static void address_hash_func(const Address
*a
, struct siphash
*state
) {
360 siphash24_compress(&a
->family
, sizeof(a
->family
), state
);
364 struct in_addr prefix
;
366 siphash24_compress(&a
->prefixlen
, sizeof(a
->prefixlen
), state
);
368 assert_se(address_ipv4_prefix(a
, &prefix
) >= 0);
369 siphash24_compress(&prefix
, sizeof(prefix
), state
);
371 siphash24_compress(&a
->in_addr
.in
, sizeof(a
->in_addr
.in
), state
);
375 siphash24_compress(&a
->in_addr
.in6
, sizeof(a
->in_addr
.in6
), state
);
377 if (in6_addr_is_null(&a
->in_addr
.in6
))
378 siphash24_compress(&a
->prefixlen
, sizeof(a
->prefixlen
), state
);
382 /* treat any other address family as AF_UNSPEC */
387 static int address_compare_func(const Address
*a1
, const Address
*a2
) {
390 r
= CMP(a1
->family
, a2
->family
);
394 switch (a1
->family
) {
396 struct in_addr p1
, p2
;
398 /* See kernel's find_matching_ifa() in net/ipv4/devinet.c */
399 r
= CMP(a1
->prefixlen
, a2
->prefixlen
);
403 assert_se(address_ipv4_prefix(a1
, &p1
) >= 0);
404 assert_se(address_ipv4_prefix(a2
, &p2
) >= 0);
405 r
= memcmp(&p1
, &p2
, sizeof(p1
));
409 return memcmp(&a1
->in_addr
.in
, &a2
->in_addr
.in
, sizeof(a1
->in_addr
.in
));
412 /* See kernel's ipv6_get_ifaddr() in net/ipv6/addrconf.c */
413 r
= memcmp(&a1
->in_addr
.in6
, &a2
->in_addr
.in6
, sizeof(a1
->in_addr
.in6
));
417 /* To distinguish IPv6 null addresses with different prefixlen, e.g. ::48 vs ::64, let's
418 * compare the prefix length. */
419 if (in6_addr_is_null(&a1
->in_addr
.in6
))
420 r
= CMP(a1
->prefixlen
, a2
->prefixlen
);
425 /* treat any other address family as AF_UNSPEC */
434 address_compare_func
);
436 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
437 address_hash_ops_free
,
440 address_compare_func
,
443 static bool address_can_update(const Address
*la
, const Address
*na
) {
450 * property | IPv4 | IPv6
451 * -----------------------------------------
453 * prefixlen | ✗ | ✗
454 * address | ✗ | ✗
457 * broadcast | ✗ | -
460 * lifetime | ✓ | ✓
461 * route metric | ✓ | ✓
462 * protocol | ✓ | ✓
464 * ✗ : cannot be changed
465 * ✓ : can be changed
468 * IPv4 : See inet_rtm_newaddr() in net/ipv4/devinet.c.
469 * IPv6 : See inet6_addr_modify() in net/ipv6/addrconf.c.
472 if (la
->family
!= na
->family
)
475 if (la
->prefixlen
!= na
->prefixlen
)
478 /* When a null address is requested, the address to be assigned/updated will be determined later. */
479 if (!address_is_static_null(na
) &&
480 in_addr_equal(la
->family
, &la
->in_addr
, &na
->in_addr
) <= 0)
483 switch (la
->family
) {
485 struct in_addr bcast
;
487 if (la
->scope
!= na
->scope
)
489 if (((la
->flags
^ na
->flags
) & KNOWN_FLAGS
& ~IPV6ONLY_FLAGS
& ~UNMANAGED_FLAGS
) != 0)
491 if (!streq_ptr(la
->label
, na
->label
))
493 if (!in4_addr_equal(&la
->in_addr_peer
.in
, &na
->in_addr_peer
.in
))
495 if (address_get_broadcast(na
, la
->link
, &bcast
) >= 0) {
496 /* If the broadcast address can be determined now, check if they match. */
497 if (!in4_addr_equal(&la
->broadcast
, &bcast
))
500 /* When a null address is requested, then the broadcast address will be
501 * automatically calculated from the acquired address, e.g.
502 * 192.168.0.10/24 -> 192.168.0.255
503 * So, here let's only check if the broadcast is the last address in the range, e.g.
504 * 0.0.0.0/24 -> 0.0.0.255 */
505 if (!FLAGS_SET(la
->broadcast
.s_addr
, htobe32(UINT32_C(0xffffffff) >> la
->prefixlen
)))
514 assert_not_reached();
520 int address_dup(const Address
*src
, Address
**ret
) {
521 _cleanup_(address_freep
) Address
*dest
= NULL
;
527 dest
= newdup(Address
, src
, 1);
531 /* clear all pointers */
532 dest
->network
= NULL
;
533 dest
->section
= NULL
;
536 dest
->netlabel
= NULL
;
537 dest
->nft_set_context
.sets
= NULL
;
538 dest
->nft_set_context
.n_sets
= 0;
540 if (src
->family
== AF_INET
) {
541 r
= free_and_strdup(&dest
->label
, src
->label
);
546 r
= free_and_strdup(&dest
->netlabel
, src
->netlabel
);
550 r
= nft_set_context_dup(&src
->nft_set_context
, &dest
->nft_set_context
);
554 *ret
= TAKE_PTR(dest
);
558 static int address_set_masquerade(Address
*address
, bool add
) {
559 union in_addr_union masked
;
563 assert(address
->link
);
565 if (!address
->link
->network
)
568 if (address
->family
== AF_INET
&&
569 !FLAGS_SET(address
->link
->network
->ip_masquerade
, ADDRESS_FAMILY_IPV4
))
572 if (address
->family
== AF_INET6
&&
573 !FLAGS_SET(address
->link
->network
->ip_masquerade
, ADDRESS_FAMILY_IPV6
))
576 if (address
->scope
>= RT_SCOPE_LINK
)
579 if (address
->ip_masquerade_done
== add
)
582 masked
= address
->in_addr
;
583 r
= in_addr_mask(address
->family
, &masked
, address
->prefixlen
);
587 r
= fw_add_masquerade(&address
->link
->manager
->fw_ctx
, add
, address
->family
, &masked
, address
->prefixlen
);
591 address
->ip_masquerade_done
= add
;
596 static void address_modify_nft_set_context(Address
*address
, bool add
, NFTSetContext
*nft_set_context
) {
600 assert(address
->link
);
601 assert(address
->link
->manager
);
602 assert(nft_set_context
);
604 if (!address
->link
->manager
->fw_ctx
) {
605 r
= fw_ctx_new(&address
->link
->manager
->fw_ctx
);
610 FOREACH_ARRAY(nft_set
, nft_set_context
->sets
, nft_set_context
->n_sets
) {
615 switch (nft_set
->source
) {
616 case NFT_SET_SOURCE_ADDRESS
:
617 r
= nft_set_element_modify_ip(address
->link
->manager
->fw_ctx
, add
, nft_set
->nfproto
, address
->family
, nft_set
->table
, nft_set
->set
,
620 case NFT_SET_SOURCE_PREFIX
:
621 r
= nft_set_element_modify_iprange(address
->link
->manager
->fw_ctx
, add
, nft_set
->nfproto
, address
->family
, nft_set
->table
, nft_set
->set
,
622 &address
->in_addr
, address
->prefixlen
);
624 case NFT_SET_SOURCE_IFINDEX
:
625 ifindex
= address
->link
->ifindex
;
626 r
= nft_set_element_modify_any(address
->link
->manager
->fw_ctx
, add
, nft_set
->nfproto
, nft_set
->table
, nft_set
->set
,
627 &ifindex
, sizeof(ifindex
));
630 assert_not_reached();
634 log_warning_errno(r
, "Failed to %s NFT set: family %s, table %s, set %s, IP address %s, ignoring",
635 add
? "add" : "delete",
636 nfproto_to_string(nft_set
->nfproto
), nft_set
->table
, nft_set
->set
,
637 IN_ADDR_PREFIX_TO_STRING(address
->family
, &address
->in_addr
, address
->prefixlen
));
639 log_debug("%s NFT set: family %s, table %s, set %s, IP address %s",
640 add
? "Added" : "Deleted",
641 nfproto_to_string(nft_set
->nfproto
), nft_set
->table
, nft_set
->set
,
642 IN_ADDR_PREFIX_TO_STRING(address
->family
, &address
->in_addr
, address
->prefixlen
));
646 static void address_modify_nft_set(Address
*address
, bool add
) {
648 assert(address
->link
);
650 if (!IN_SET(address
->family
, AF_INET
, AF_INET6
))
653 if (!address
->link
->network
)
656 switch (address
->source
) {
657 case NETWORK_CONFIG_SOURCE_DHCP4
:
658 return address_modify_nft_set_context(address
, add
, &address
->link
->network
->dhcp_nft_set_context
);
659 case NETWORK_CONFIG_SOURCE_DHCP6
:
660 return address_modify_nft_set_context(address
, add
, &address
->link
->network
->dhcp6_nft_set_context
);
661 case NETWORK_CONFIG_SOURCE_DHCP_PD
:
662 return address_modify_nft_set_context(address
, add
, &address
->link
->network
->dhcp_pd_nft_set_context
);
663 case NETWORK_CONFIG_SOURCE_NDISC
:
664 return address_modify_nft_set_context(address
, add
, &address
->link
->network
->ndisc_nft_set_context
);
665 case NETWORK_CONFIG_SOURCE_STATIC
:
666 return address_modify_nft_set_context(address
, add
, &address
->nft_set_context
);
672 static int address_add(Link
*link
, Address
*address
) {
678 r
= set_ensure_put(&link
->addresses
, &address_hash_ops_free
, address
);
684 address
->link
= link
;
688 static int address_update(Address
*address
) {
689 Link
*link
= ASSERT_PTR(ASSERT_PTR(address
)->link
);
692 if (address_is_ready(address
) &&
693 address
->family
== AF_INET6
&&
694 in6_addr_is_link_local(&address
->in_addr
.in6
) &&
695 in6_addr_is_null(&link
->ipv6ll_address
)) {
697 link
->ipv6ll_address
= address
->in_addr
.in6
;
699 r
= link_ipv6ll_gained(link
);
704 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
707 r
= address_set_masquerade(address
, /* add = */ true);
709 return log_link_warning_errno(link
, r
, "Could not enable IP masquerading: %m");
711 address_add_netlabel(address
);
713 address_modify_nft_set(address
, /* add = */ true);
715 if (address_is_ready(address
) && address
->callback
) {
716 r
= address
->callback(address
);
721 link_update_operstate(link
, /* also_update_master = */ true);
722 link_check_ready(link
);
726 static int address_drop(Address
*address
) {
727 Link
*link
= ASSERT_PTR(ASSERT_PTR(address
)->link
);
730 r
= address_set_masquerade(address
, /* add = */ false);
732 log_link_warning_errno(link
, r
, "Failed to disable IP masquerading, ignoring: %m");
734 address_modify_nft_set(address
, /* add = */ false);
736 address_del_netlabel(address
);
738 address_free(address
);
740 link_update_operstate(link
, /* also_update_master = */ true);
741 link_check_ready(link
);
745 static bool address_match_null(const Address
*a
, const Address
*null_address
) {
747 assert(null_address
);
749 if (!a
->requested_as_null
)
752 /* Currently, null address is supported only by static addresses. Note that static
753 * address may be set as foreign during reconfiguring the interface. */
754 if (!IN_SET(a
->source
, NETWORK_CONFIG_SOURCE_FOREIGN
, NETWORK_CONFIG_SOURCE_STATIC
))
757 if (a
->family
!= null_address
->family
)
760 if (a
->prefixlen
!= null_address
->prefixlen
)
766 static int address_get_request(Link
*link
, const Address
*address
, Request
**ret
) {
770 assert(link
->manager
);
773 req
= ordered_set_get(
774 link
->manager
->request_queue
,
777 .type
= REQUEST_TYPE_ADDRESS
,
778 .userdata
= (void*) address
,
779 .hash_func
= (hash_func_t
) address_hash_func
,
780 .compare_func
= (compare_func_t
) address_compare_func
,
788 if (address_is_static_null(address
))
789 ORDERED_SET_FOREACH(req
, link
->manager
->request_queue
) {
790 if (req
->link
!= link
)
792 if (req
->type
!= REQUEST_TYPE_ADDRESS
)
795 if (!address_match_null(req
->userdata
, address
))
807 int address_get(Link
*link
, const Address
*in
, Address
**ret
) {
813 a
= set_get(link
->addresses
, in
);
820 /* Find matching address that originally requested as null address. */
821 if (address_is_static_null(in
))
822 SET_FOREACH(a
, link
->addresses
) {
823 if (!address_match_null(a
, in
))
834 int address_get_harder(Link
*link
, const Address
*in
, Address
**ret
) {
841 if (address_get(link
, in
, ret
) >= 0)
844 r
= address_get_request(link
, in
, &req
);
849 *ret
= ASSERT_PTR(req
->userdata
);
854 int link_get_address(Link
*link
, int family
, const union in_addr_union
*address
, unsigned char prefixlen
, Address
**ret
) {
859 assert(IN_SET(family
, AF_INET
, AF_INET6
));
862 /* This find an Address object on the link which matches the given address and prefix length
863 * and does not have peer address. When the prefixlen is zero, then an Address object with an
864 * arbitrary prefixlen will be returned. */
866 if (family
== AF_INET6
|| prefixlen
!= 0) {
867 _cleanup_(address_freep
) Address
*tmp
= NULL
;
869 /* In this case, we can use address_get(). */
871 r
= address_new(&tmp
);
875 tmp
->family
= family
;
876 tmp
->in_addr
= *address
;
877 tmp
->prefixlen
= prefixlen
;
879 r
= address_get(link
, tmp
, &a
);
883 if (family
== AF_INET6
) {
884 /* IPv6 addresses are managed without peer address and prefix length. Hence, we need
885 * to check them explicitly. */
886 if (in_addr_is_set(family
, &a
->in_addr_peer
))
888 if (prefixlen
!= 0 && a
->prefixlen
!= prefixlen
)
898 SET_FOREACH(a
, link
->addresses
) {
899 if (a
->family
!= family
)
902 if (!in_addr_equal(family
, &a
->in_addr
, address
))
905 if (in_addr_is_set(family
, &a
->in_addr_peer
))
917 int manager_get_address(Manager
*manager
, int family
, const union in_addr_union
*address
, unsigned char prefixlen
, Address
**ret
) {
921 assert(IN_SET(family
, AF_INET
, AF_INET6
));
924 HASHMAP_FOREACH(link
, manager
->links_by_index
) {
925 if (!IN_SET(link
->state
, LINK_STATE_CONFIGURING
, LINK_STATE_CONFIGURED
))
928 if (link_get_address(link
, family
, address
, prefixlen
, ret
) >= 0)
935 bool manager_has_address(Manager
*manager
, int family
, const union in_addr_union
*address
, bool check_ready
) {
939 assert(IN_SET(family
, AF_INET
, AF_INET6
));
942 if (manager_get_address(manager
, family
, address
, 0, &a
) < 0)
945 return check_ready
? address_is_ready(a
) : (address_exists(a
) && address_lifetime_is_valid(a
));
948 const char* format_lifetime(char *buf
, size_t l
, usec_t lifetime_usec
) {
952 if (lifetime_usec
== USEC_INFINITY
)
955 sprintf(buf
, "for ");
956 /* format_timespan() never fails */
957 assert_se(format_timespan(buf
+ 4, l
- 4, usec_sub_unsigned(lifetime_usec
, now(CLOCK_BOOTTIME
)), USEC_PER_SEC
));
961 static void log_address_debug(const Address
*address
, const char *str
, const Link
*link
) {
962 _cleanup_free_
char *state
= NULL
, *flags_str
= NULL
, *scope_str
= NULL
;
971 (void) network_config_state_to_string_alloc(address
->state
, &state
);
973 const char *peer
= in_addr_is_set(address
->family
, &address
->in_addr_peer
) ?
974 IN_ADDR_TO_STRING(address
->family
, &address
->in_addr_peer
) : NULL
;
976 const char *broadcast
= (address
->family
== AF_INET
&& in4_addr_is_set(&address
->broadcast
)) ?
977 IN4_ADDR_TO_STRING(&address
->broadcast
) : NULL
;
979 (void) address_flags_to_string_alloc(address
->flags
, address
->family
, &flags_str
);
980 (void) route_scope_to_string_alloc(address
->scope
, &scope_str
);
982 log_link_debug(link
, "%s %s address (%s): %s%s%s/%u%s%s (valid %s, preferred %s), flags: %s, scope: %s%s%s",
983 str
, strna(network_config_source_to_string(address
->source
)), strna(state
),
984 IN_ADDR_TO_STRING(address
->family
, &address
->in_addr
),
985 peer
? " peer " : "", strempty(peer
), address
->prefixlen
,
986 broadcast
? " broadcast " : "", strempty(broadcast
),
987 FORMAT_LIFETIME(address
->lifetime_valid_usec
),
988 FORMAT_LIFETIME(address
->lifetime_preferred_usec
),
989 strna(flags_str
), strna(scope_str
),
990 address
->family
== AF_INET
? ", label: " : "",
991 address
->family
== AF_INET
? strna(address
->label
) : "");
994 static int address_set_netlink_message(const Address
*address
, sd_netlink_message
*m
, Link
*link
) {
1002 r
= sd_rtnl_message_addr_set_prefixlen(m
, address
->prefixlen
);
1006 /* On remove, only IFA_F_MANAGETEMPADDR flag for IPv6 addresses are used. But anyway, set all
1007 * flags except tentative flag here unconditionally. Without setting the flag, the template
1008 * addresses generated by kernel will not be removed automatically when the main address is
1010 flags
= address
->flags
& ~IFA_F_TENTATIVE
;
1011 r
= sd_rtnl_message_addr_set_flags(m
, flags
& 0xff);
1015 if ((flags
& ~0xff) != 0) {
1016 r
= sd_netlink_message_append_u32(m
, IFA_FLAGS
, flags
);
1021 r
= netlink_message_append_in_addr_union(m
, IFA_LOCAL
, address
->family
, &address
->in_addr
);
1028 static int address_remove_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Link
*link
) {
1034 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
1037 r
= sd_netlink_message_get_errno(m
);
1038 if (r
< 0 && r
!= -EADDRNOTAVAIL
)
1039 log_link_message_warning_errno(link
, m
, r
, "Could not drop address");
1044 int address_remove(Address
*address
) {
1045 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
1051 assert(IN_SET(address
->family
, AF_INET
, AF_INET6
));
1052 assert(address
->link
);
1053 assert(address
->link
->ifindex
> 0);
1054 assert(address
->link
->manager
);
1055 assert(address
->link
->manager
->rtnl
);
1057 link
= address
->link
;
1059 log_address_debug(address
, "Removing", link
);
1061 r
= sd_rtnl_message_new_addr(link
->manager
->rtnl
, &m
, RTM_DELADDR
,
1062 link
->ifindex
, address
->family
);
1064 return log_link_warning_errno(link
, r
, "Could not allocate RTM_DELADDR message: %m");
1066 r
= address_set_netlink_message(address
, m
, link
);
1068 return log_link_warning_errno(link
, r
, "Could not set netlink attributes: %m");
1070 r
= netlink_call_async(link
->manager
->rtnl
, NULL
, m
,
1071 address_remove_handler
,
1072 link_netlink_destroy_callback
, link
);
1074 return log_link_warning_errno(link
, r
, "Could not send rtnetlink message: %m");
1078 address_enter_removing(address
);
1079 if (address_get_request(link
, address
, &req
) >= 0)
1080 address_enter_removing(req
->userdata
);
1082 /* The operational state is determined by address state and carrier state. Hence, if we remove
1083 * an address, the operational state may be changed. */
1084 link_update_operstate(link
, true);
1088 int address_remove_and_drop(Address
*address
) {
1092 address_cancel_request(address
);
1094 if (address_exists(address
))
1095 return address_remove(address
);
1097 return address_drop(address
);
1100 bool link_address_is_dynamic(const Link
*link
, const Address
*address
) {
1106 if (address
->lifetime_preferred_usec
!= USEC_INFINITY
)
1109 /* Even when the address is leased from a DHCP server, networkd assign the address
1110 * without lifetime when KeepConfiguration=dhcp. So, let's check that we have
1111 * corresponding routes with RTPROT_DHCP. */
1112 SET_FOREACH(route
, link
->routes
) {
1113 if (route
->source
!= NETWORK_CONFIG_SOURCE_FOREIGN
)
1116 /* The route is not assigned yet, or already removed. Ignoring. */
1117 if (!route_exists(route
))
1120 if (route
->protocol
!= RTPROT_DHCP
)
1123 if (address
->family
!= route
->family
)
1126 if (in_addr_equal(address
->family
, &address
->in_addr
, &route
->prefsrc
))
1133 int link_drop_ipv6ll_addresses(Link
*link
) {
1134 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
, *reply
= NULL
;
1138 assert(link
->manager
);
1139 assert(link
->manager
->rtnl
);
1141 /* IPv6LL address may be in the tentative state, and in that case networkd has not received it.
1142 * So, we need to dump all IPv6 addresses. */
1144 if (link_may_have_ipv6ll(link
, /* check_multicast = */ false))
1147 r
= sd_rtnl_message_new_addr(link
->manager
->rtnl
, &req
, RTM_GETADDR
, link
->ifindex
, AF_INET6
);
1151 r
= sd_netlink_message_set_request_dump(req
, true);
1155 r
= sd_netlink_call(link
->manager
->rtnl
, req
, 0, &reply
);
1159 for (sd_netlink_message
*addr
= reply
; addr
; addr
= sd_netlink_message_next(addr
)) {
1160 _cleanup_(address_freep
) Address
*a
= NULL
;
1161 unsigned char flags
, prefixlen
;
1162 struct in6_addr address
;
1166 /* NETLINK_GET_STRICT_CHK socket option is supported since kernel 4.20. To support
1167 * older kernels, we need to check ifindex here. */
1168 r
= sd_rtnl_message_addr_get_ifindex(addr
, &ifindex
);
1170 log_link_debug_errno(link
, r
, "rtnl: received address message without valid ifindex, ignoring: %m");
1172 } else if (link
->ifindex
!= ifindex
)
1175 r
= sd_rtnl_message_addr_get_flags(addr
, &flags
);
1177 log_link_debug_errno(link
, r
, "rtnl: received address message without valid flags, ignoring: %m");
1181 r
= sd_rtnl_message_addr_get_prefixlen(addr
, &prefixlen
);
1183 log_link_debug_errno(link
, r
, "rtnl: received address message without prefixlen, ignoring: %m");
1187 if (sd_netlink_message_read_in6_addr(addr
, IFA_LOCAL
, NULL
) >= 0)
1188 /* address with peer, ignoring. */
1191 r
= sd_netlink_message_read_in6_addr(addr
, IFA_ADDRESS
, &address
);
1193 log_link_debug_errno(link
, r
, "rtnl: received address message without valid address, ignoring: %m");
1197 if (!in6_addr_is_link_local(&address
))
1200 r
= address_new(&a
);
1204 a
->family
= AF_INET6
;
1205 a
->in_addr
.in6
= address
;
1206 a
->prefixlen
= prefixlen
;
1209 if (address_get(link
, a
, &existing
) < 0) {
1210 r
= address_add(link
, a
);
1214 existing
= TAKE_PTR(a
);
1217 r
= address_remove(existing
);
1225 int link_drop_foreign_addresses(Link
*link
) {
1230 assert(link
->network
);
1232 /* First, mark all addresses. */
1233 SET_FOREACH(address
, link
->addresses
) {
1234 /* We consider IPv6LL addresses to be managed by the kernel, or dropped in link_drop_ipv6ll_addresses() */
1235 if (address
->family
== AF_INET6
&& in6_addr_is_link_local(&address
->in_addr
.in6
))
1238 /* Do not remove localhost address (127.0.0.1 and ::1) */
1239 if (link
->flags
& IFF_LOOPBACK
&& in_addr_is_localhost_one(address
->family
, &address
->in_addr
) > 0)
1242 /* Ignore addresses we configured. */
1243 if (address
->source
!= NETWORK_CONFIG_SOURCE_FOREIGN
)
1246 /* Ignore addresses not assigned yet or already removing. */
1247 if (!address_exists(address
))
1250 /* link_address_is_dynamic() is slightly heavy. Let's call the function only when KeepConfiguration= is set. */
1251 if (IN_SET(link
->network
->keep_configuration
, KEEP_CONFIGURATION_DHCP
, KEEP_CONFIGURATION_STATIC
) &&
1252 link_address_is_dynamic(link
, address
) == (link
->network
->keep_configuration
== KEEP_CONFIGURATION_DHCP
))
1255 address_mark(address
);
1258 /* Then, unmark requested addresses. */
1259 ORDERED_HASHMAP_FOREACH(address
, link
->network
->addresses_by_section
) {
1262 if (address_get(link
, address
, &existing
) < 0)
1265 if (!address_can_update(existing
, address
))
1268 /* Found matching static configuration. Keep the existing address. */
1269 address_unmark(existing
);
1272 /* Finally, remove all marked addresses. */
1273 SET_FOREACH(address
, link
->addresses
) {
1274 if (!address_is_marked(address
))
1277 RET_GATHER(r
, address_remove(address
));
1283 int link_drop_managed_addresses(Link
*link
) {
1289 SET_FOREACH(address
, link
->addresses
) {
1290 /* Do not touch addresses managed by kernel or other tools. */
1291 if (address
->source
== NETWORK_CONFIG_SOURCE_FOREIGN
)
1294 /* Ignore addresses not assigned yet or already removing. */
1295 if (!address_exists(address
))
1298 RET_GATHER(r
, address_remove(address
));
1304 void link_foreignize_addresses(Link
*link
) {
1309 SET_FOREACH(address
, link
->addresses
)
1310 address
->source
= NETWORK_CONFIG_SOURCE_FOREIGN
;
1313 static int address_acquire(Link
*link
, const Address
*original
, Address
**ret
) {
1314 _cleanup_(address_freep
) Address
*na
= NULL
;
1315 union in_addr_union in_addr
;
1322 /* Something useful was configured? just use it */
1323 if (in_addr_is_set(original
->family
, &original
->in_addr
))
1324 return address_dup(original
, ret
);
1326 /* The address is configured to be 0.0.0.0 or [::] by the user?
1327 * Then let's acquire something more useful from the pool. */
1328 r
= address_pool_acquire(link
->manager
, original
->family
, original
->prefixlen
, &in_addr
);
1334 /* Pick first address in range for ourselves. */
1335 if (original
->family
== AF_INET
)
1336 in_addr
.in
.s_addr
= in_addr
.in
.s_addr
| htobe32(1);
1337 else if (original
->family
== AF_INET6
)
1338 in_addr
.in6
.s6_addr
[15] |= 1;
1340 r
= address_dup(original
, &na
);
1344 na
->in_addr
= in_addr
;
1346 *ret
= TAKE_PTR(na
);
1350 int address_configure_handler_internal(sd_netlink
*rtnl
, sd_netlink_message
*m
, Link
*link
, const char *error_msg
) {
1358 r
= sd_netlink_message_get_errno(m
);
1359 if (r
< 0 && r
!= -EEXIST
) {
1360 log_link_message_warning_errno(link
, m
, r
, error_msg
);
1361 link_enter_failed(link
);
1368 static int address_configure(const Address
*address
, const struct ifa_cacheinfo
*c
, Link
*link
, Request
*req
) {
1369 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
1373 assert(IN_SET(address
->family
, AF_INET
, AF_INET6
));
1376 assert(link
->ifindex
> 0);
1377 assert(link
->manager
);
1378 assert(link
->manager
->rtnl
);
1381 log_address_debug(address
, "Configuring", link
);
1383 r
= sd_rtnl_message_new_addr_update(link
->manager
->rtnl
, &m
, link
->ifindex
, address
->family
);
1387 r
= address_set_netlink_message(address
, m
, link
);
1391 r
= sd_rtnl_message_addr_set_scope(m
, address
->scope
);
1395 if (address
->family
== AF_INET6
|| in_addr_is_set(address
->family
, &address
->in_addr_peer
)) {
1396 r
= netlink_message_append_in_addr_union(m
, IFA_ADDRESS
, address
->family
, &address
->in_addr_peer
);
1399 } else if (in4_addr_is_set(&address
->broadcast
)) {
1400 r
= sd_netlink_message_append_in_addr(m
, IFA_BROADCAST
, &address
->broadcast
);
1405 if (address
->family
== AF_INET
&& address
->label
) {
1406 r
= sd_netlink_message_append_string(m
, IFA_LABEL
, address
->label
);
1411 r
= sd_netlink_message_append_cache_info(m
, IFA_CACHEINFO
, c
);
1415 r
= sd_netlink_message_append_u32(m
, IFA_RT_PRIORITY
, address
->route_metric
);
1419 return request_call_netlink_async(link
->manager
->rtnl
, m
, req
);
1422 static bool address_is_ready_to_configure(Link
*link
, const Address
*address
) {
1426 if (!link_is_ready_to_configure(link
, false))
1429 if (!ipv4acd_bound(link
, address
))
1432 /* Refuse adding more than the limit */
1433 if (set_size(link
->addresses
) >= ADDRESSES_PER_LINK_MAX
)
1439 static int address_process_request(Request
*req
, Link
*link
, Address
*address
) {
1440 struct Address
*existing
;
1441 struct ifa_cacheinfo c
;
1448 if (!address_is_ready_to_configure(link
, address
))
1451 address_set_cinfo(link
->manager
, address
, &c
);
1452 if (c
.ifa_valid
== 0) {
1453 log_link_debug(link
, "Refuse to configure %s address %s, as its valid lifetime is zero.",
1454 network_config_source_to_string(address
->source
),
1455 IN_ADDR_PREFIX_TO_STRING(address
->family
, &address
->in_addr
, address
->prefixlen
));
1457 address_cancel_requesting(address
);
1458 if (address_get(link
, address
, &existing
) >= 0)
1459 address_cancel_requesting(existing
);
1463 r
= address_configure(address
, &c
, link
, req
);
1465 return log_link_warning_errno(link
, r
, "Failed to configure address: %m");
1467 address_enter_configuring(address
);
1468 if (address_get(link
, address
, &existing
) >= 0)
1469 address_enter_configuring(existing
);
1474 int link_request_address(
1476 const Address
*address
,
1477 unsigned *message_counter
,
1478 address_netlink_handler_t netlink_handler
,
1481 _cleanup_(address_freep
) Address
*tmp
= NULL
;
1482 Address
*existing
= NULL
;
1487 assert(address
->source
!= NETWORK_CONFIG_SOURCE_FOREIGN
);
1489 if (address
->lifetime_valid_usec
== 0)
1490 /* The requested address is outdated. Let's ignore the request. */
1493 if (address_get(link
, address
, &existing
) < 0) {
1494 if (address_get_request(link
, address
, NULL
) >= 0)
1495 return 0; /* already requested, skipping. */
1497 r
= address_acquire(link
, address
, &tmp
);
1499 return log_link_warning_errno(link
, r
, "Failed to acquire an address from pool: %m");
1501 /* Consider address tentative until we get the real flags from the kernel */
1502 tmp
->flags
|= IFA_F_TENTATIVE
;
1505 r
= address_dup(address
, &tmp
);
1509 /* Copy already assigned address when it is requested as a null address. */
1510 if (address_is_static_null(address
))
1511 tmp
->in_addr
= existing
->in_addr
;
1513 /* Copy state for logging below. */
1514 tmp
->state
= existing
->state
;
1517 address_set_broadcast(tmp
, link
);
1519 r
= ipv4acd_configure(link
, tmp
);
1523 log_address_debug(tmp
, "Requesting", link
);
1524 r
= link_queue_request_safe(link
, REQUEST_TYPE_ADDRESS
,
1528 address_compare_func
,
1529 address_process_request
,
1530 message_counter
, netlink_handler
, ret
);
1532 return log_link_warning_errno(link
, r
, "Failed to request address: %m");
1536 address_enter_requesting(tmp
);
1538 address_enter_requesting(existing
);
1544 static int static_address_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Request
*req
, Link
*link
, Address
*address
) {
1549 r
= address_configure_handler_internal(rtnl
, m
, link
, "Failed to set static address");
1553 if (link
->static_address_messages
== 0) {
1554 log_link_debug(link
, "Addresses set");
1555 link
->static_addresses_configured
= true;
1556 link_check_ready(link
);
1562 int link_request_static_address(Link
*link
, const Address
*address
) {
1565 assert(address
->source
== NETWORK_CONFIG_SOURCE_STATIC
);
1567 return link_request_address(link
, address
, &link
->static_address_messages
,
1568 static_address_handler
, NULL
);
1571 int link_request_static_addresses(Link
*link
) {
1576 assert(link
->network
);
1578 link
->static_addresses_configured
= false;
1580 ORDERED_HASHMAP_FOREACH(a
, link
->network
->addresses_by_section
) {
1581 r
= link_request_static_address(link
, a
);
1586 r
= link_request_radv_addresses(link
);
1590 if (link
->static_address_messages
== 0) {
1591 link
->static_addresses_configured
= true;
1592 link_check_ready(link
);
1594 log_link_debug(link
, "Setting addresses");
1595 link_set_state(link
, LINK_STATE_CONFIGURING
);
1601 void address_cancel_request(Address
*address
) {
1605 assert(address
->link
);
1607 if (!address_is_requesting(address
))
1611 .link
= address
->link
,
1612 .type
= REQUEST_TYPE_ADDRESS
,
1613 .userdata
= address
,
1614 .hash_func
= (hash_func_t
) address_hash_func
,
1615 .compare_func
= (compare_func_t
) address_compare_func
,
1618 request_detach(address
->link
->manager
, &req
);
1619 address_cancel_requesting(address
);
1622 int manager_rtnl_process_address(sd_netlink
*rtnl
, sd_netlink_message
*message
, Manager
*m
) {
1623 _cleanup_(address_freep
) Address
*tmp
= NULL
;
1624 struct ifa_cacheinfo cinfo
;
1627 Address
*address
= NULL
;
1628 Request
*req
= NULL
;
1629 bool is_new
= false;
1636 if (sd_netlink_message_is_error(message
)) {
1637 r
= sd_netlink_message_get_errno(message
);
1639 log_message_warning_errno(message
, r
, "rtnl: failed to receive address message, ignoring");
1644 r
= sd_netlink_message_get_type(message
, &type
);
1646 log_warning_errno(r
, "rtnl: could not get message type, ignoring: %m");
1648 } else if (!IN_SET(type
, RTM_NEWADDR
, RTM_DELADDR
)) {
1649 log_warning("rtnl: received unexpected message type %u when processing address, ignoring.", type
);
1653 r
= sd_rtnl_message_addr_get_ifindex(message
, &ifindex
);
1655 log_warning_errno(r
, "rtnl: could not get ifindex from message, ignoring: %m");
1657 } else if (ifindex
<= 0) {
1658 log_warning("rtnl: received address message with invalid ifindex %d, ignoring.", ifindex
);
1662 r
= link_get_by_index(m
, ifindex
, &link
);
1664 /* when enumerating we might be out of sync, but we will get the address again, so just
1666 if (!m
->enumerating
)
1667 log_warning("rtnl: received address for link '%d' we don't know about, ignoring.", ifindex
);
1671 r
= address_new(&tmp
);
1675 /* First, read minimal information to make address_get() work below. */
1677 r
= sd_rtnl_message_addr_get_family(message
, &tmp
->family
);
1679 log_link_warning(link
, "rtnl: received address message without family, ignoring.");
1681 } else if (!IN_SET(tmp
->family
, AF_INET
, AF_INET6
)) {
1682 log_link_debug(link
, "rtnl: received address message with invalid family '%i', ignoring.", tmp
->family
);
1686 r
= sd_rtnl_message_addr_get_prefixlen(message
, &tmp
->prefixlen
);
1688 log_link_warning_errno(link
, r
, "rtnl: received address message without prefixlen, ignoring: %m");
1692 switch (tmp
->family
) {
1694 r
= sd_netlink_message_read_in_addr(message
, IFA_LOCAL
, &tmp
->in_addr
.in
);
1696 log_link_warning_errno(link
, r
, "rtnl: received address message without valid address, ignoring: %m");
1700 r
= sd_netlink_message_read_in_addr(message
, IFA_ADDRESS
, &tmp
->in_addr_peer
.in
);
1701 if (r
< 0 && r
!= -ENODATA
) {
1702 log_link_warning_errno(link
, r
, "rtnl: could not get peer address from address message, ignoring: %m");
1704 } else if (r
>= 0) {
1705 if (in4_addr_equal(&tmp
->in_addr
.in
, &tmp
->in_addr_peer
.in
))
1706 tmp
->in_addr_peer
= IN_ADDR_NULL
;
1712 r
= sd_netlink_message_read_in6_addr(message
, IFA_LOCAL
, &tmp
->in_addr
.in6
);
1714 /* Have peer address. */
1715 r
= sd_netlink_message_read_in6_addr(message
, IFA_ADDRESS
, &tmp
->in_addr_peer
.in6
);
1717 log_link_warning_errno(link
, r
, "rtnl: could not get peer address from address message, ignoring: %m");
1720 } else if (r
== -ENODATA
) {
1721 /* Does not have peer address. */
1722 r
= sd_netlink_message_read_in6_addr(message
, IFA_ADDRESS
, &tmp
->in_addr
.in6
);
1724 log_link_warning_errno(link
, r
, "rtnl: received address message without valid address, ignoring: %m");
1728 log_link_warning_errno(link
, r
, "rtnl: could not get local address from address message, ignoring: %m");
1735 assert_not_reached();
1738 /* Then, find the managed Address and Request objects corresponding to the received address. */
1739 (void) address_get(link
, tmp
, &address
);
1740 (void) address_get_request(link
, tmp
, &req
);
1742 if (type
== RTM_DELADDR
) {
1744 address_enter_removed(address
);
1745 log_address_debug(address
, "Forgetting removed", link
);
1746 (void) address_drop(address
);
1748 log_address_debug(tmp
, "Kernel removed unknown", link
);
1751 address_enter_removed(req
->userdata
);
1757 /* If we did not know the address, then save it. */
1758 r
= address_add(link
, tmp
);
1760 log_link_warning_errno(link
, r
, "Failed to remember foreign address %s, ignoring: %m",
1761 IN_ADDR_PREFIX_TO_STRING(tmp
->family
, &tmp
->in_addr
, tmp
->prefixlen
));
1764 address
= TAKE_PTR(tmp
);
1769 /* Otherwise, update the managed Address object with the netlink notification. */
1770 address
->prefixlen
= tmp
->prefixlen
;
1771 address
->in_addr_peer
= tmp
->in_addr_peer
;
1774 /* Also update information that cannot be obtained through netlink notification. */
1775 if (req
&& req
->waiting_reply
) {
1776 Address
*a
= ASSERT_PTR(req
->userdata
);
1778 address
->source
= a
->source
;
1779 address
->provider
= a
->provider
;
1780 (void) free_and_strdup_warn(&address
->netlabel
, a
->netlabel
);
1781 nft_set_context_clear(&address
->nft_set_context
);
1782 (void) nft_set_context_dup(&a
->nft_set_context
, &address
->nft_set_context
);
1783 address
->requested_as_null
= a
->requested_as_null
;
1784 address
->callback
= a
->callback
;
1787 /* Then, update miscellaneous info. */
1788 r
= sd_rtnl_message_addr_get_scope(message
, &address
->scope
);
1790 log_link_debug_errno(link
, r
, "rtnl: received address message without scope, ignoring: %m");
1792 if (address
->family
== AF_INET
) {
1793 _cleanup_free_
char *label
= NULL
;
1795 r
= sd_netlink_message_read_string_strdup(message
, IFA_LABEL
, &label
);
1797 if (!streq_ptr(label
, link
->ifname
))
1798 free_and_replace(address
->label
, label
);
1799 } else if (r
!= -ENODATA
)
1800 log_link_debug_errno(link
, r
, "rtnl: could not get label from address message, ignoring: %m");
1802 r
= sd_netlink_message_read_in_addr(message
, IFA_BROADCAST
, &address
->broadcast
);
1803 if (r
< 0 && r
!= -ENODATA
)
1804 log_link_debug_errno(link
, r
, "rtnl: could not get broadcast from address message, ignoring: %m");
1807 r
= sd_netlink_message_read_u32(message
, IFA_FLAGS
, &address
->flags
);
1808 if (r
== -ENODATA
) {
1809 unsigned char flags
;
1811 /* For old kernels. */
1812 r
= sd_rtnl_message_addr_get_flags(message
, &flags
);
1814 address
->flags
= flags
;
1816 log_link_debug_errno(link
, r
, "rtnl: failed to read IFA_FLAGS attribute, ignoring: %m");
1818 r
= sd_netlink_message_read_cache_info(message
, IFA_CACHEINFO
, &cinfo
);
1820 address_set_lifetime(m
, address
, &cinfo
);
1821 else if (r
!= -ENODATA
)
1822 log_link_debug_errno(link
, r
, "rtnl: failed to read IFA_CACHEINFO attribute, ignoring: %m");
1824 r
= sd_netlink_message_read_u32(message
, IFA_RT_PRIORITY
, &address
->route_metric
);
1825 if (r
< 0 && r
!= -ENODATA
)
1826 log_link_debug_errno(link
, r
, "rtnl: failed to read IFA_RT_PRIORITY attribute, ignoring: %m");
1828 address_enter_configured(address
);
1830 address_enter_configured(req
->userdata
);
1832 log_address_debug(address
, is_new
? "Received new": "Received updated", link
);
1834 /* address_update() logs internally, so we don't need to here. */
1835 r
= address_update(address
);
1837 link_enter_failed(link
);
1842 int config_parse_broadcast(
1844 const char *filename
,
1846 const char *section
,
1847 unsigned section_line
,
1854 Network
*network
= userdata
;
1855 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
1856 union in_addr_union u
;
1865 r
= address_new_static(network
, filename
, section_line
, &n
);
1869 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1870 "Failed to allocate new address, ignoring assignment: %m");
1874 if (isempty(rvalue
)) {
1875 /* The broadcast address will be calculated based on Address=, and set if the link is
1876 * not a wireguard interface. Here, we do not check or set n->family. */
1877 n
->broadcast
= (struct in_addr
) {};
1878 n
->set_broadcast
= -1;
1883 r
= parse_boolean(rvalue
);
1885 /* The broadcast address will be calculated based on Address=. Here, we do not check or
1887 n
->broadcast
= (struct in_addr
) {};
1888 n
->set_broadcast
= r
;
1893 if (n
->family
== AF_INET6
) {
1894 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1895 "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue
);
1899 r
= in_addr_from_string(AF_INET
, rvalue
, &u
);
1901 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1902 "Broadcast is invalid, ignoring assignment: %s", rvalue
);
1905 if (in4_addr_is_null(&u
.in
)) {
1906 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1907 "Broadcast cannot be ANY address, ignoring assignment: %s", rvalue
);
1911 n
->broadcast
= u
.in
;
1912 n
->set_broadcast
= true;
1913 n
->family
= AF_INET
;
1919 int config_parse_address(
1921 const char *filename
,
1923 const char *section
,
1924 unsigned section_line
,
1931 Network
*network
= userdata
;
1932 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
1933 union in_addr_union buffer
;
1934 unsigned char prefixlen
;
1943 if (streq(section
, "Network"))
1944 /* we are not in an Address section, so use line number instead. */
1945 r
= address_new_static(network
, filename
, line
, &n
);
1947 r
= address_new_static(network
, filename
, section_line
, &n
);
1951 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1952 "Failed to allocate new address, ignoring assignment: %m");
1956 /* Address=address/prefixlen */
1957 r
= in_addr_prefix_from_string_auto_internal(rvalue
, PREFIXLEN_REFUSE
, &f
, &buffer
, &prefixlen
);
1959 r
= in_addr_prefix_from_string_auto(rvalue
, &f
, &buffer
, &prefixlen
);
1961 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1962 "Address '%s' is specified without prefix length. Assuming the prefix length is %u. "
1963 "Please specify the prefix length explicitly.", rvalue
, prefixlen
);
1966 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
, "Invalid address '%s', ignoring assignment: %m", rvalue
);
1970 if (n
->family
!= AF_UNSPEC
&& f
!= n
->family
) {
1971 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0, "Address is incompatible, ignoring assignment: %s", rvalue
);
1975 if (in_addr_is_null(f
, &buffer
)) {
1976 /* Will use address from address pool. Note that for ipv6 case, prefix of the address
1977 * pool is 8, but 40 bit is used by the global ID and 16 bit by the subnet ID. So,
1978 * let's limit the prefix length to 64 or larger. See RFC4193. */
1979 if ((f
== AF_INET
&& prefixlen
< 8) ||
1980 (f
== AF_INET6
&& prefixlen
< 64)) {
1981 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1982 "Null address with invalid prefixlen='%u', ignoring assignment: %s",
1989 n
->prefixlen
= prefixlen
;
1991 if (streq(lvalue
, "Address")) {
1992 n
->in_addr
= buffer
;
1993 n
->requested_as_null
= !in_addr_is_set(n
->family
, &n
->in_addr
);
1995 n
->in_addr_peer
= buffer
;
2001 int config_parse_label(
2003 const char *filename
,
2005 const char *section
,
2006 unsigned section_line
,
2013 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
2014 Network
*network
= userdata
;
2023 r
= address_new_static(network
, filename
, section_line
, &n
);
2027 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
2028 "Failed to allocate new address, ignoring assignment: %m");
2032 if (isempty(rvalue
)) {
2033 n
->label
= mfree(n
->label
);
2038 if (!address_label_valid(rvalue
)) {
2039 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
2040 "Interface label is too long or invalid, ignoring assignment: %s", rvalue
);
2044 r
= free_and_strdup(&n
->label
, rvalue
);
2052 int config_parse_lifetime(
2054 const char *filename
,
2056 const char *section
,
2057 unsigned section_line
,
2064 Network
*network
= userdata
;
2065 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
2075 r
= address_new_static(network
, filename
, section_line
, &n
);
2079 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
2080 "Failed to allocate new address, ignoring assignment: %m");
2084 /* We accept only "forever", "infinity", empty, or "0". */
2085 if (STR_IN_SET(rvalue
, "forever", "infinity", ""))
2087 else if (streq(rvalue
, "0"))
2090 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
2091 "Invalid PreferredLifetime= value, ignoring: %s", rvalue
);
2095 n
->lifetime_preferred_usec
= k
;
2101 int config_parse_address_flags(
2103 const char *filename
,
2105 const char *section
,
2106 unsigned section_line
,
2113 Network
*network
= userdata
;
2114 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
2123 r
= address_new_static(network
, filename
, section_line
, &n
);
2127 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
2128 "Failed to allocate new address, ignoring assignment: %m");
2132 r
= parse_boolean(rvalue
);
2134 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
2135 "Failed to parse %s=, ignoring: %s", lvalue
, rvalue
);
2139 if (streq(lvalue
, "AddPrefixRoute"))
2142 SET_FLAG(n
->flags
, ltype
, r
);
2148 int config_parse_address_scope(
2150 const char *filename
,
2152 const char *section
,
2153 unsigned section_line
,
2160 Network
*network
= userdata
;
2161 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
2170 r
= address_new_static(network
, filename
, section_line
, &n
);
2174 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
2175 "Failed to allocate new address, ignoring assignment: %m");
2179 r
= route_scope_from_string(rvalue
);
2181 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
2182 "Could not parse address scope \"%s\", ignoring assignment: %m", rvalue
);
2187 n
->scope_set
= true;
2192 int config_parse_address_route_metric(
2194 const char *filename
,
2196 const char *section
,
2197 unsigned section_line
,
2204 Network
*network
= userdata
;
2205 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
2214 r
= address_new_static(network
, filename
, section_line
, &n
);
2218 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
2219 "Failed to allocate new address, ignoring assignment: %m");
2223 r
= safe_atou32(rvalue
, &n
->route_metric
);
2225 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
2226 "Could not parse %s=, ignoring assignment: %s", lvalue
, rvalue
);
2234 int config_parse_duplicate_address_detection(
2236 const char *filename
,
2238 const char *section
,
2239 unsigned section_line
,
2246 Network
*network
= userdata
;
2247 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
2256 r
= address_new_static(network
, filename
, section_line
, &n
);
2260 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
2261 "Failed to allocate new address, ignoring assignment: %m");
2265 r
= parse_boolean(rvalue
);
2267 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
2268 "For historical reasons, %s=%s means %s=%s. "
2269 "Please use 'both', 'ipv4', 'ipv6' or 'none' instead.",
2270 lvalue
, rvalue
, lvalue
, r
? "none" : "both");
2271 n
->duplicate_address_detection
= r
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_YES
;
2276 AddressFamily a
= duplicate_address_detection_address_family_from_string(rvalue
);
2278 log_syntax(unit
, LOG_WARNING
, filename
, line
, a
,
2279 "Failed to parse %s=, ignoring: %s", lvalue
, rvalue
);
2282 n
->duplicate_address_detection
= a
;
2288 int config_parse_address_netlabel(
2290 const char *filename
,
2292 const char *section
,
2293 unsigned section_line
,
2300 Network
*network
= userdata
;
2301 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
2311 r
= address_new_static(network
, filename
, section_line
, &n
);
2315 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
2316 "Failed to allocate new address, ignoring assignment: %m");
2320 r
= config_parse_string(unit
, filename
, line
, section
, section_line
,
2321 lvalue
, CONFIG_PARSE_STRING_SAFE
, rvalue
, &n
->netlabel
, network
);
2329 static void address_section_adjust_broadcast(Address
*address
) {
2331 assert(address
->section
);
2333 if (!in4_addr_is_set(&address
->broadcast
))
2336 if (address
->family
== AF_INET6
)
2337 log_warning("%s: broadcast address is set for an IPv6 address. "
2338 "Ignoring Broadcast= setting in the [Address] section from line %u.",
2339 address
->section
->filename
, address
->section
->line
);
2340 else if (address
->prefixlen
> 30)
2341 log_warning("%s: broadcast address is set for an IPv4 address with prefix length larger than 30. "
2342 "Ignoring Broadcast= setting in the [Address] section from line %u.",
2343 address
->section
->filename
, address
->section
->line
);
2344 else if (in4_addr_is_set(&address
->in_addr_peer
.in
))
2345 log_warning("%s: broadcast address is set for an IPv4 address with peer address. "
2346 "Ignoring Broadcast= setting in the [Address] section from line %u.",
2347 address
->section
->filename
, address
->section
->line
);
2348 else if (!in4_addr_is_set(&address
->in_addr
.in
))
2349 log_warning("%s: broadcast address is set for an IPv4 address with null address. "
2350 "Ignoring Broadcast= setting in the [Address] section from line %u.",
2351 address
->section
->filename
, address
->section
->line
);
2353 /* Otherwise, keep the specified broadcast address. */
2356 address
->broadcast
.s_addr
= 0;
2359 int address_section_verify(Address
*address
) {
2360 if (section_is_invalid(address
->section
))
2363 if (address
->family
== AF_UNSPEC
) {
2364 assert(address
->section
);
2366 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
2367 "%s: Address section without Address= field was configured. "
2368 "Ignoring [Address] section from line %u.",
2369 address
->section
->filename
, address
->section
->line
);
2372 if (address
->family
== AF_INET6
&& !socket_ipv6_is_supported())
2373 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
2374 "%s: an IPv6 address was configured, but the kernel does not support IPv6. "
2375 "Ignoring [Address] section from line %u.",
2376 address
->section
->filename
, address
->section
->line
);
2378 assert(IN_SET(address
->family
, AF_INET
, AF_INET6
));
2380 address_section_adjust_broadcast(address
);
2382 if (address
->family
== AF_INET6
&& address
->label
) {
2383 log_warning("%s: address label is set for IPv6 address in the [Address] section from line %u. "
2384 "Ignoring Label= setting.",
2385 address
->section
->filename
, address
->section
->line
);
2387 address
->label
= mfree(address
->label
);
2390 if (!address
->scope_set
) {
2391 if (in_addr_is_localhost(address
->family
, &address
->in_addr
) > 0)
2392 address
->scope
= RT_SCOPE_HOST
;
2393 else if (in_addr_is_link_local(address
->family
, &address
->in_addr
) > 0)
2394 address
->scope
= RT_SCOPE_LINK
;
2397 if (address
->duplicate_address_detection
< 0) {
2398 if (address
->family
== AF_INET6
)
2399 address
->duplicate_address_detection
= ADDRESS_FAMILY_IPV6
;
2400 else if (in4_addr_is_link_local(&address
->in_addr
.in
))
2401 address
->duplicate_address_detection
= ADDRESS_FAMILY_IPV4
;
2403 address
->duplicate_address_detection
= ADDRESS_FAMILY_NO
;
2404 } else if (address
->duplicate_address_detection
== ADDRESS_FAMILY_IPV6
&& address
->family
== AF_INET
)
2405 log_warning("%s: DuplicateAddressDetection=ipv6 is specified for IPv4 address, ignoring.",
2406 address
->section
->filename
);
2407 else if (address
->duplicate_address_detection
== ADDRESS_FAMILY_IPV4
&& address
->family
== AF_INET6
)
2408 log_warning("%s: DuplicateAddressDetection=ipv4 is specified for IPv6 address, ignoring.",
2409 address
->section
->filename
);
2411 if (address
->family
== AF_INET6
&&
2412 !FLAGS_SET(address
->duplicate_address_detection
, ADDRESS_FAMILY_IPV6
))
2413 address
->flags
|= IFA_F_NODAD
;
2415 uint32_t filtered_flags
= address
->family
== AF_INET
?
2416 address
->flags
& KNOWN_FLAGS
& ~UNMANAGED_FLAGS
& ~IPV6ONLY_FLAGS
:
2417 address
->flags
& KNOWN_FLAGS
& ~UNMANAGED_FLAGS
;
2418 if (address
->flags
!= filtered_flags
) {
2419 _cleanup_free_
char *str
= NULL
;
2421 (void) address_flags_to_string_alloc(filtered_flags
, address
->family
, &str
);
2422 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
2423 "%s: unexpected address flags \"%s\" were configured. "
2424 "Ignoring [Address] section from line %u.",
2425 address
->section
->filename
, strna(str
), address
->section
->line
);
2431 int network_drop_invalid_addresses(Network
*network
) {
2432 _cleanup_set_free_ Set
*addresses
= NULL
;
2438 ORDERED_HASHMAP_FOREACH(address
, network
->addresses_by_section
) {
2441 if (address_section_verify(address
) < 0) {
2442 /* Drop invalid [Address] sections or Address= settings in [Network].
2443 * Note that address_free() will drop the address from addresses_by_section. */
2444 address_free(address
);
2448 /* Always use the setting specified later. So, remove the previously assigned setting. */
2449 dup
= set_remove(addresses
, address
);
2451 log_warning("%s: Duplicated address %s is specified at line %u and %u, "
2452 "dropping the address setting specified at line %u.",
2453 dup
->section
->filename
,
2454 IN_ADDR_PREFIX_TO_STRING(address
->family
, &address
->in_addr
, address
->prefixlen
),
2455 address
->section
->line
,
2456 dup
->section
->line
, dup
->section
->line
);
2457 /* address_free() will drop the address from addresses_by_section. */
2461 /* Use address_hash_ops, instead of address_hash_ops_free. Otherwise, the Address objects
2463 r
= set_ensure_put(&addresses
, &address_hash_ops
, address
);
2469 r
= network_adjust_dhcp_server(network
, &addresses
);
2476 int config_parse_address_ip_nft_set(
2478 const char *filename
,
2480 const char *section
,
2481 unsigned section_line
,
2488 Network
*network
= userdata
;
2489 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
2497 r
= address_new_static(network
, filename
, section_line
, &n
);
2501 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
2502 "Failed to allocate a new address, ignoring assignment: %m");
2506 r
= config_parse_nft_set(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &n
->nft_set_context
, network
);