1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 #include "alloc-util.h"
6 #include "conf-parser.h"
7 #include "firewall-util.h"
8 #include "memory-util.h"
9 #include "missing_network.h"
10 #include "netlink-util.h"
11 #include "networkd-address.h"
12 #include "networkd-manager.h"
13 #include "parse-util.h"
15 #include "socket-util.h"
16 #include "string-util.h"
20 #define ADDRESSES_PER_LINK_MAX 2048U
21 #define STATIC_ADDRESSES_PER_NETWORK_MAX 1024U
23 int generate_ipv6_eui_64_address(Link
*link
, struct in6_addr
*ret
) {
27 /* see RFC4291 section 2.5.1 */
28 ret
->s6_addr
[8] = link
->mac
.ether_addr_octet
[0];
29 ret
->s6_addr
[8] ^= 1 << 1;
30 ret
->s6_addr
[9] = link
->mac
.ether_addr_octet
[1];
31 ret
->s6_addr
[10] = link
->mac
.ether_addr_octet
[2];
32 ret
->s6_addr
[11] = 0xff;
33 ret
->s6_addr
[12] = 0xfe;
34 ret
->s6_addr
[13] = link
->mac
.ether_addr_octet
[3];
35 ret
->s6_addr
[14] = link
->mac
.ether_addr_octet
[4];
36 ret
->s6_addr
[15] = link
->mac
.ether_addr_octet
[5];
41 int address_new(Address
**ret
) {
42 _cleanup_(address_freep
) Address
*address
= NULL
;
44 address
= new(Address
, 1);
48 *address
= (Address
) {
50 .scope
= RT_SCOPE_UNIVERSE
,
51 .cinfo
.ifa_prefered
= CACHE_INFO_INFINITY_LIFE_TIME
,
52 .cinfo
.ifa_valid
= CACHE_INFO_INFINITY_LIFE_TIME
,
53 .duplicate_address_detection
= ADDRESS_FAMILY_IPV6
,
57 *ret
= TAKE_PTR(address
);
62 static int address_new_static(Network
*network
, const char *filename
, unsigned section_line
, Address
**ret
) {
63 _cleanup_(network_config_section_freep
) NetworkConfigSection
*n
= NULL
;
64 _cleanup_(address_freep
) Address
*address
= NULL
;
69 assert(!!filename
== (section_line
> 0));
72 r
= network_config_section_new(filename
, section_line
, &n
);
76 address
= hashmap_get(network
->addresses_by_section
, n
);
78 *ret
= TAKE_PTR(address
);
84 if (network
->n_static_addresses
>= STATIC_ADDRESSES_PER_NETWORK_MAX
)
87 r
= address_new(&address
);
91 address
->network
= network
;
92 LIST_APPEND(addresses
, network
->static_addresses
, address
);
93 network
->n_static_addresses
++;
96 address
->section
= TAKE_PTR(n
);
98 r
= hashmap_ensure_allocated(&network
->addresses_by_section
, &network_config_hash_ops
);
102 r
= hashmap_put(network
->addresses_by_section
, address
->section
, address
);
107 *ret
= TAKE_PTR(address
);
112 void address_free(Address
*address
) {
116 if (address
->network
) {
117 LIST_REMOVE(addresses
, address
->network
->static_addresses
, address
);
118 assert(address
->network
->n_static_addresses
> 0);
119 address
->network
->n_static_addresses
--;
121 if (address
->section
)
122 hashmap_remove(address
->network
->addresses_by_section
, address
->section
);
125 if (address
->link
&& !address
->acd
) {
126 set_remove(address
->link
->addresses
, address
);
127 set_remove(address
->link
->addresses_foreign
, address
);
128 set_remove(address
->link
->static_addresses
, address
);
129 if (address
->link
->dhcp_address
== address
)
130 address
->link
->dhcp_address
= NULL
;
131 if (address
->link
->dhcp_address_old
== address
)
132 address
->link
->dhcp_address_old
= NULL
;
133 set_remove(address
->link
->dhcp6_addresses
, address
);
134 set_remove(address
->link
->dhcp6_addresses_old
, address
);
135 set_remove(address
->link
->dhcp6_pd_addresses
, address
);
136 set_remove(address
->link
->dhcp6_pd_addresses_old
, address
);
137 set_remove(address
->link
->ndisc_addresses
, address
);
138 set_remove(address
->link
->ndisc_addresses_old
, address
);
140 if (in_addr_equal(AF_INET6
, &address
->in_addr
, (const union in_addr_union
*) &address
->link
->ipv6ll_address
))
141 memzero(&address
->link
->ipv6ll_address
, sizeof(struct in6_addr
));
144 sd_ipv4acd_unref(address
->acd
);
146 network_config_section_free(address
->section
);
147 free(address
->label
);
151 static uint32_t address_prefix(const Address
*a
) {
154 /* make sure we don't try to shift by 32.
155 * See ISO/IEC 9899:TC3 ยง 6.5.7.3. */
156 if (a
->prefixlen
== 0)
159 if (a
->in_addr_peer
.in
.s_addr
!= 0)
160 return be32toh(a
->in_addr_peer
.in
.s_addr
) >> (32 - a
->prefixlen
);
162 return be32toh(a
->in_addr
.in
.s_addr
) >> (32 - a
->prefixlen
);
165 static void address_hash_func(const Address
*a
, struct siphash
*state
) {
168 siphash24_compress(&a
->family
, sizeof(a
->family
), state
);
172 siphash24_compress(&a
->prefixlen
, sizeof(a
->prefixlen
), state
);
175 uint32_t prefix
= address_prefix(a
);
176 siphash24_compress(&prefix
, sizeof(prefix
), state
);
181 siphash24_compress(&a
->in_addr
, FAMILY_ADDRESS_SIZE(a
->family
), state
);
185 /* treat any other address family as AF_UNSPEC */
190 static int address_compare_func(const Address
*a1
, const Address
*a2
) {
193 r
= CMP(a1
->family
, a2
->family
);
197 switch (a1
->family
) {
198 /* use the same notion of equality as the kernel does */
200 r
= CMP(a1
->prefixlen
, a2
->prefixlen
);
204 uint32_t prefix1
= address_prefix(a1
);
205 uint32_t prefix2
= address_prefix(a2
);
206 r
= CMP(prefix1
, prefix2
);
212 return memcmp(&a1
->in_addr
, &a2
->in_addr
, FAMILY_ADDRESS_SIZE(a1
->family
));
214 /* treat any other address family as AF_UNSPEC */
219 DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(address_hash_ops
, Address
, address_hash_func
, address_compare_func
, address_free
);
221 bool address_equal(Address
*a1
, Address
*a2
) {
228 return address_compare_func(a1
, a2
) == 0;
231 static int address_establish(Address
*address
, Link
*link
) {
238 masq
= link
->network
&&
239 link
->network
->ip_masquerade
&&
240 address
->family
== AF_INET
&&
241 address
->scope
< RT_SCOPE_LINK
;
243 /* Add firewall entry if this is requested */
244 if (address
->ip_masquerade_done
!= masq
) {
245 union in_addr_union masked
= address
->in_addr
;
246 in_addr_mask(address
->family
, &masked
, address
->prefixlen
);
248 r
= fw_add_masquerade(masq
, AF_INET
, 0, &masked
, address
->prefixlen
, NULL
, NULL
, 0);
252 address
->ip_masquerade_done
= masq
;
258 static int address_add_internal(Link
*link
, Set
**addresses
,
260 const union in_addr_union
*in_addr
,
261 unsigned char prefixlen
,
263 _cleanup_(address_freep
) Address
*address
= NULL
;
270 r
= address_new(&address
);
274 address
->family
= family
;
275 address
->in_addr
= *in_addr
;
276 address
->prefixlen
= prefixlen
;
277 /* Consider address tentative until we get the real flags from the kernel */
278 address
->flags
= IFA_F_TENTATIVE
;
280 r
= set_ensure_put(addresses
, &address_hash_ops
, address
);
286 address
->link
= link
;
294 int address_add_foreign(Link
*link
, int family
, const union in_addr_union
*in_addr
, unsigned char prefixlen
, Address
**ret
) {
295 return address_add_internal(link
, &link
->addresses_foreign
, family
, in_addr
, prefixlen
, ret
);
298 int address_add(Link
*link
, int family
, const union in_addr_union
*in_addr
, unsigned char prefixlen
, Address
**ret
) {
302 r
= address_get(link
, family
, in_addr
, prefixlen
, &address
);
304 /* Address does not exist, create a new one */
305 r
= address_add_internal(link
, &link
->addresses
, family
, in_addr
, prefixlen
, &address
);
309 /* Take over a foreign address */
310 r
= set_ensure_put(&link
->addresses
, &address_hash_ops
, address
);
314 set_remove(link
->addresses_foreign
, address
);
316 /* Already exists, do nothing */
327 static int address_release(Address
*address
) {
331 assert(address
->link
);
333 /* Remove masquerading firewall entry if it was added */
334 if (address
->ip_masquerade_done
) {
335 union in_addr_union masked
= address
->in_addr
;
336 in_addr_mask(address
->family
, &masked
, address
->prefixlen
);
338 r
= fw_add_masquerade(false, AF_INET
, 0, &masked
, address
->prefixlen
, NULL
, NULL
, 0);
342 address
->ip_masquerade_done
= false;
352 const struct ifa_cacheinfo
*cinfo
) {
359 assert_return(address
->link
, 1);
361 if (IN_SET(address
->link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
364 ready
= address_is_ready(address
);
366 address
->flags
= flags
;
367 address
->scope
= scope
;
368 address
->cinfo
= *cinfo
;
370 link_update_operstate(address
->link
, true);
371 link_check_ready(address
->link
);
373 if (!ready
&& address_is_ready(address
)) {
374 if (address
->callback
) {
375 r
= address
->callback(address
);
380 if (address
->family
== AF_INET6
&&
381 in_addr_is_link_local(AF_INET6
, &address
->in_addr
) > 0 &&
382 IN6_IS_ADDR_UNSPECIFIED(&address
->link
->ipv6ll_address
) > 0) {
384 r
= link_ipv6ll_gained(address
->link
, &address
->in_addr
.in6
);
393 int address_drop(Address
*address
) {
400 ready
= address_is_ready(address
);
401 link
= address
->link
;
403 r
= address_release(address
);
405 log_link_warning_errno(link
, r
, "Failed to disable IP masquerading, ignoring: %m");
407 address_free(address
);
409 link_update_operstate(link
, true);
412 link_check_ready(link
);
417 int address_get(Link
*link
,
419 const union in_addr_union
*in_addr
,
420 unsigned char prefixlen
,
423 Address address
, *existing
;
428 address
= (Address
) {
431 .prefixlen
= prefixlen
,
434 existing
= set_get(link
->addresses
, &address
);
441 existing
= set_get(link
->addresses_foreign
, &address
);
451 static bool address_exists_internal(Set
*addresses
, int family
, const union in_addr_union
*in_addr
) {
455 SET_FOREACH(address
, addresses
, i
) {
456 if (address
->family
!= family
)
458 if (in_addr_equal(address
->family
, &address
->in_addr
, in_addr
))
465 bool address_exists(Link
*link
, int family
, const union in_addr_union
*in_addr
) {
467 assert(IN_SET(family
, AF_INET
, AF_INET6
));
470 if (address_exists_internal(link
->addresses
, family
, in_addr
))
472 if (address_exists_internal(link
->addresses_foreign
, family
, in_addr
))
477 static int address_remove_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Link
*link
) {
482 assert(link
->ifname
);
484 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
487 r
= sd_netlink_message_get_errno(m
);
488 if (r
< 0 && r
!= -EADDRNOTAVAIL
)
489 log_link_message_warning_errno(link
, m
, r
, "Could not drop address");
491 (void) manager_rtnl_process_address(rtnl
, m
, link
->manager
);
499 link_netlink_message_handler_t callback
) {
501 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
;
505 assert(IN_SET(address
->family
, AF_INET
, AF_INET6
));
507 assert(link
->ifindex
> 0);
508 assert(link
->manager
);
509 assert(link
->manager
->rtnl
);
512 _cleanup_free_
char *b
= NULL
;
514 (void) in_addr_to_string(address
->family
, &address
->in_addr
, &b
);
515 log_link_debug(link
, "Removing address %s", strna(b
));
518 r
= sd_rtnl_message_new_addr(link
->manager
->rtnl
, &req
, RTM_DELADDR
,
519 link
->ifindex
, address
->family
);
521 return log_link_error_errno(link
, r
, "Could not allocate RTM_DELADDR message: %m");
523 r
= sd_rtnl_message_addr_set_prefixlen(req
, address
->prefixlen
);
525 return log_link_error_errno(link
, r
, "Could not set prefixlen: %m");
527 r
= netlink_message_append_in_addr_union(req
, IFA_LOCAL
, address
->family
, &address
->in_addr
);
529 return log_link_error_errno(link
, r
, "Could not append IFA_LOCAL attribute: %m");
531 r
= netlink_call_async(link
->manager
->rtnl
, NULL
, req
,
532 callback
?: address_remove_handler
,
533 link_netlink_destroy_callback
, link
);
535 return log_link_error_errno(link
, r
, "Could not send rtnetlink message: %m");
542 static int address_acquire(Link
*link
, Address
*original
, Address
**ret
) {
543 union in_addr_union in_addr
= IN_ADDR_NULL
;
544 struct in_addr broadcast
= {};
545 _cleanup_(address_freep
) Address
*na
= NULL
;
552 /* Something useful was configured? just use it */
553 r
= in_addr_is_null(original
->family
, &original
->in_addr
);
557 /* The address is configured to be 0.0.0.0 or [::] by the user?
558 * Then let's acquire something more useful from the pool. */
559 r
= manager_address_pool_acquire(link
->manager
, original
->family
, original
->prefixlen
, &in_addr
);
565 if (original
->family
== AF_INET
) {
566 /* Pick first address in range for ourselves ... */
567 in_addr
.in
.s_addr
= in_addr
.in
.s_addr
| htobe32(1);
569 /* .. and use last as broadcast address */
570 if (original
->prefixlen
> 30)
571 broadcast
.s_addr
= 0;
573 broadcast
.s_addr
= in_addr
.in
.s_addr
| htobe32(0xFFFFFFFFUL
>> original
->prefixlen
);
574 } else if (original
->family
== AF_INET6
)
575 in_addr
.in6
.s6_addr
[15] |= 1;
577 r
= address_new(&na
);
581 na
->family
= original
->family
;
582 na
->prefixlen
= original
->prefixlen
;
583 na
->scope
= original
->scope
;
584 na
->cinfo
= original
->cinfo
;
586 if (original
->label
) {
587 na
->label
= strdup(original
->label
);
592 na
->broadcast
= broadcast
;
593 na
->in_addr
= in_addr
;
595 LIST_PREPEND(addresses
, link
->pool_addresses
, na
);
602 int address_configure(
605 link_netlink_message_handler_t callback
,
609 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
;
614 assert(IN_SET(address
->family
, AF_INET
, AF_INET6
));
616 assert(link
->ifindex
> 0);
617 assert(link
->manager
);
618 assert(link
->manager
->rtnl
);
621 /* If this is a new address, then refuse adding more than the limit */
622 if (address_get(link
, address
->family
, &address
->in_addr
, address
->prefixlen
, NULL
) <= 0 &&
623 set_size(link
->addresses
) >= ADDRESSES_PER_LINK_MAX
)
624 return log_link_error_errno(link
, SYNTHETIC_ERRNO(E2BIG
),
625 "Too many addresses are configured, refusing: %m");
627 r
= address_acquire(link
, address
, &address
);
629 return log_link_error_errno(link
, r
, "Failed to acquire an address from pool: %m");
632 _cleanup_free_
char *str
= NULL
;
634 (void) in_addr_to_string(address
->family
, &address
->in_addr
, &str
);
635 log_link_debug(link
, "%s address: %s", update
? "Updating" : "Configuring", strna(str
));
639 r
= sd_rtnl_message_new_addr_update(link
->manager
->rtnl
, &req
,
640 link
->ifindex
, address
->family
);
642 r
= sd_rtnl_message_new_addr(link
->manager
->rtnl
, &req
, RTM_NEWADDR
,
643 link
->ifindex
, address
->family
);
645 return log_link_error_errno(link
, r
, "Could not allocate RTM_NEWADDR message: %m");
647 r
= sd_rtnl_message_addr_set_prefixlen(req
, address
->prefixlen
);
649 return log_link_error_errno(link
, r
, "Could not set prefixlen: %m");
651 address
->flags
|= IFA_F_PERMANENT
;
653 if (address
->home_address
)
654 address
->flags
|= IFA_F_HOMEADDRESS
;
656 if (!FLAGS_SET(address
->duplicate_address_detection
, ADDRESS_FAMILY_IPV6
))
657 address
->flags
|= IFA_F_NODAD
;
659 if (address
->manage_temporary_address
)
660 address
->flags
|= IFA_F_MANAGETEMPADDR
;
662 if (!address
->prefix_route
)
663 address
->flags
|= IFA_F_NOPREFIXROUTE
;
665 if (address
->autojoin
)
666 address
->flags
|= IFA_F_MCAUTOJOIN
;
668 r
= sd_rtnl_message_addr_set_flags(req
, (address
->flags
& 0xff));
670 return log_link_error_errno(link
, r
, "Could not set flags: %m");
672 if (address
->flags
& ~0xff) {
673 r
= sd_netlink_message_append_u32(req
, IFA_FLAGS
, address
->flags
);
675 return log_link_error_errno(link
, r
, "Could not set extended flags: %m");
678 r
= sd_rtnl_message_addr_set_scope(req
, address
->scope
);
680 return log_link_error_errno(link
, r
, "Could not set scope: %m");
682 r
= netlink_message_append_in_addr_union(req
, IFA_LOCAL
, address
->family
, &address
->in_addr
);
684 return log_link_error_errno(link
, r
, "Could not append IFA_LOCAL attribute: %m");
686 if (in_addr_is_null(address
->family
, &address
->in_addr_peer
) == 0) {
687 r
= netlink_message_append_in_addr_union(req
, IFA_ADDRESS
, address
->family
, &address
->in_addr_peer
);
689 return log_link_error_errno(link
, r
, "Could not append IFA_ADDRESS attribute: %m");
690 } else if (address
->family
== AF_INET
&& address
->prefixlen
<= 30) {
691 r
= sd_netlink_message_append_in_addr(req
, IFA_BROADCAST
, &address
->broadcast
);
693 return log_link_error_errno(link
, r
, "Could not append IFA_BROADCAST attribute: %m");
696 if (address
->label
) {
697 r
= sd_netlink_message_append_string(req
, IFA_LABEL
, address
->label
);
699 return log_link_error_errno(link
, r
, "Could not append IFA_LABEL attribute: %m");
702 r
= sd_netlink_message_append_cache_info(req
, IFA_CACHEINFO
, &address
->cinfo
);
704 return log_link_error_errno(link
, r
, "Could not append IFA_CACHEINFO attribute: %m");
706 r
= address_establish(address
, link
);
708 log_link_warning_errno(link
, r
, "Could not enable IP masquerading, ignoring: %m");
710 r
= netlink_call_async(link
->manager
->rtnl
, NULL
, req
, callback
, link_netlink_destroy_callback
, link
);
712 address_release(address
);
713 return log_link_error_errno(link
, r
, "Could not send rtnetlink message: %m");
718 if (address
->family
== AF_INET6
&& !in_addr_is_null(address
->family
, &address
->in_addr_peer
))
719 r
= address_add(link
, address
->family
, &address
->in_addr_peer
, address
->prefixlen
, &a
);
721 r
= address_add(link
, address
->family
, &address
->in_addr
, address
->prefixlen
, &a
);
723 address_release(address
);
724 return log_link_error_errno(link
, r
, "Could not add address: %m");
728 assert(address
->family
== AF_INET
);
730 _cleanup_free_
char *pretty
= NULL
;
732 (void) in_addr_to_string(address
->family
, &address
->in_addr
, &pretty
);
733 log_link_debug(link
, "Starting IPv4ACD client. Probing address %s", strna(pretty
));
736 r
= sd_ipv4acd_start(address
->acd
, true);
738 log_link_warning_errno(link
, r
, "Failed to start IPv4ACD client, ignoring: %m");
747 static void static_address_on_acd(sd_ipv4acd
*acd
, int event
, void *userdata
) {
748 _cleanup_free_
char *pretty
= NULL
;
756 address
= (Address
*) userdata
;
757 link
= address
->link
;
759 (void) in_addr_to_string(address
->family
, &address
->in_addr
, &pretty
);
761 case SD_IPV4ACD_EVENT_STOP
:
762 log_link_debug(link
, "Stopping ACD client...");
765 case SD_IPV4ACD_EVENT_BIND
:
766 log_link_debug(link
, "Successfully claimed address %s", strna(pretty
));
767 link_check_ready(link
);
770 case SD_IPV4ACD_EVENT_CONFLICT
:
771 log_link_warning(link
, "DAD conflict. Dropping address %s", strna(pretty
));
772 r
= address_remove(address
, link
, NULL
);
774 log_link_error_errno(link
, r
, "Failed to drop DAD conflicted address %s", strna(pretty
));;
776 link_check_ready(link
);
780 assert_not_reached("Invalid IPv4ACD event.");
783 sd_ipv4acd_stop(acd
);
788 int configure_ipv4_duplicate_address_detection(Link
*link
, Address
*address
) {
793 assert(address
->family
== AF_INET
);
794 assert(!address
->link
&& address
->network
);
796 address
->link
= link
;
798 r
= sd_ipv4acd_new(&address
->acd
);
802 r
= sd_ipv4acd_attach_event(address
->acd
, NULL
, 0);
806 r
= sd_ipv4acd_set_ifindex(address
->acd
, link
->ifindex
);
810 r
= sd_ipv4acd_set_mac(address
->acd
, &link
->mac
);
814 r
= sd_ipv4acd_set_address(address
->acd
, &address
->in_addr
.in
);
818 r
= sd_ipv4acd_set_callback(address
->acd
, static_address_on_acd
, address
);
825 int config_parse_broadcast(
827 const char *filename
,
830 unsigned section_line
,
837 Network
*network
= userdata
;
838 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
847 r
= address_new_static(network
, filename
, section_line
, &n
);
851 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
852 "Failed to allocate new address, ignoring assignment: %m");
856 if (n
->family
== AF_INET6
) {
857 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
858 "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue
);
862 r
= in_addr_from_string(AF_INET
, rvalue
, (union in_addr_union
*) &n
->broadcast
);
864 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
865 "Broadcast is invalid, ignoring assignment: %s", rvalue
);
875 int config_parse_address(const char *unit
,
876 const char *filename
,
879 unsigned section_line
,
886 Network
*network
= userdata
;
887 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
888 union in_addr_union buffer
;
889 unsigned char prefixlen
;
898 if (streq(section
, "Network")) {
899 /* we are not in an Address section, so treat
900 * this as the special '0' section */
901 r
= address_new_static(network
, NULL
, 0, &n
);
903 r
= address_new_static(network
, filename
, section_line
, &n
);
907 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
908 "Failed to allocate new address, ignoring assignment: %m");
912 /* Address=address/prefixlen */
913 r
= in_addr_prefix_from_string_auto_internal(rvalue
, PREFIXLEN_REFUSE
, &f
, &buffer
, &prefixlen
);
915 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
916 "An address '%s' is specified without prefix length. "
917 "The behavior of parsing addresses without prefix length will be changed in the future release. "
918 "Please specify prefix length explicitly.", rvalue
);
920 r
= in_addr_prefix_from_string_auto_internal(rvalue
, PREFIXLEN_LEGACY
, &f
, &buffer
, &prefixlen
);
923 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
, "Invalid address '%s', ignoring assignment: %m", rvalue
);
927 if (n
->family
!= AF_UNSPEC
&& f
!= n
->family
) {
928 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0, "Address is incompatible, ignoring assignment: %s", rvalue
);
932 if (in_addr_is_null(f
, &buffer
)) {
933 /* Will use address from address pool. Note that for ipv6 case, prefix of the address
934 * pool is 8, but 40 bit is used by the global ID and 16 bit by the subnet ID. So,
935 * let's limit the prefix length to 64 or larger. See RFC4193. */
936 if ((f
== AF_INET
&& prefixlen
< 8) ||
937 (f
== AF_INET6
&& prefixlen
< 64)) {
938 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
939 "Null address with invalid prefixlen='%u', ignoring assignment: %s",
946 n
->prefixlen
= prefixlen
;
948 if (streq(lvalue
, "Address"))
951 n
->in_addr_peer
= buffer
;
953 if (n
->family
== AF_INET
&& n
->broadcast
.s_addr
== 0 && n
->prefixlen
<= 30)
954 n
->broadcast
.s_addr
= n
->in_addr
.in
.s_addr
| htobe32(0xfffffffflu
>> n
->prefixlen
);
961 int config_parse_label(
963 const char *filename
,
966 unsigned section_line
,
973 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
974 Network
*network
= userdata
;
983 r
= address_new_static(network
, filename
, section_line
, &n
);
987 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
988 "Failed to allocate new address, ignoring assignment: %m");
992 if (!address_label_valid(rvalue
)) {
993 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
994 "Interface label is too long or invalid, ignoring assignment: %s", rvalue
);
998 r
= free_and_strdup(&n
->label
, rvalue
);
1006 int config_parse_lifetime(const char *unit
,
1007 const char *filename
,
1009 const char *section
,
1010 unsigned section_line
,
1016 Network
*network
= userdata
;
1017 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
1027 r
= address_new_static(network
, filename
, section_line
, &n
);
1031 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1032 "Failed to allocate new address, ignoring assignment: %m");
1036 /* We accept only "forever", "infinity", empty, or "0". */
1037 if (STR_IN_SET(rvalue
, "forever", "infinity", ""))
1038 k
= CACHE_INFO_INFINITY_LIFE_TIME
;
1039 else if (streq(rvalue
, "0"))
1042 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1043 "Invalid PreferredLifetime= value, ignoring: %s", rvalue
);
1047 n
->cinfo
.ifa_prefered
= k
;
1053 int config_parse_address_flags(const char *unit
,
1054 const char *filename
,
1056 const char *section
,
1057 unsigned section_line
,
1063 Network
*network
= userdata
;
1064 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
1073 r
= address_new_static(network
, filename
, section_line
, &n
);
1077 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1078 "Failed to allocate new address, ignoring assignment: %m");
1082 r
= parse_boolean(rvalue
);
1084 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1085 "Failed to parse %s=, ignoring: %s", lvalue
, rvalue
);
1089 if (streq(lvalue
, "HomeAddress"))
1090 n
->home_address
= r
;
1091 else if (streq(lvalue
, "ManageTemporaryAddress"))
1092 n
->manage_temporary_address
= r
;
1093 else if (streq(lvalue
, "PrefixRoute"))
1094 n
->prefix_route
= !r
;
1095 else if (streq(lvalue
, "AddPrefixRoute"))
1096 n
->prefix_route
= r
;
1097 else if (streq(lvalue
, "AutoJoin"))
1100 assert_not_reached("Invalid address flag type.");
1106 int config_parse_address_scope(const char *unit
,
1107 const char *filename
,
1109 const char *section
,
1110 unsigned section_line
,
1116 Network
*network
= userdata
;
1117 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
1126 r
= address_new_static(network
, filename
, section_line
, &n
);
1130 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1131 "Failed to allocate new address, ignoring assignment: %m");
1135 if (streq(rvalue
, "host"))
1136 n
->scope
= RT_SCOPE_HOST
;
1137 else if (streq(rvalue
, "link"))
1138 n
->scope
= RT_SCOPE_LINK
;
1139 else if (streq(rvalue
, "global"))
1140 n
->scope
= RT_SCOPE_UNIVERSE
;
1142 r
= safe_atou8(rvalue
, &n
->scope
);
1144 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1145 "Could not parse address scope \"%s\", ignoring assignment: %m", rvalue
);
1150 n
->scope_set
= true;
1155 int config_parse_duplicate_address_detection(
1157 const char *filename
,
1159 const char *section
,
1160 unsigned section_line
,
1166 Network
*network
= userdata
;
1167 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
1177 r
= address_new_static(network
, filename
, section_line
, &n
);
1181 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1182 "Failed to allocate new address, ignoring assignment: %m");
1186 r
= parse_boolean(rvalue
);
1188 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1189 "For historical reasons, %s=%s means %s=%s. "
1190 "Please use 'both', 'ipv4', 'ipv6' or 'none' instead.",
1191 lvalue
, rvalue
, lvalue
, r
? "none" : "both");
1192 n
->duplicate_address_detection
= r
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_YES
;
1197 a
= duplicate_address_detection_address_family_from_string(rvalue
);
1199 log_syntax(unit
, LOG_WARNING
, filename
, line
, SYNTHETIC_ERRNO(EINVAL
),
1200 "Failed to parse %s=, ignoring: %s", lvalue
, rvalue
);
1204 n
->duplicate_address_detection
= a
;
1209 bool address_is_ready(const Address
*a
) {
1212 return !(a
->flags
& IFA_F_TENTATIVE
);
1215 int address_section_verify(Address
*address
) {
1216 if (section_is_invalid(address
->section
))
1219 if (address
->family
== AF_UNSPEC
) {
1220 assert(address
->section
);
1222 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
1223 "%s: Address section without Address= field configured. "
1224 "Ignoring [Address] section from line %u.",
1225 address
->section
->filename
, address
->section
->line
);
1228 if (!address
->scope_set
&& in_addr_is_localhost(address
->family
, &address
->in_addr
) > 0)
1229 address
->scope
= RT_SCOPE_HOST
;