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 "networkd-ndisc.h"
14 #include "parse-util.h"
16 #include "socket-util.h"
17 #include "string-util.h"
21 #define ADDRESSES_PER_LINK_MAX 2048U
22 #define STATIC_ADDRESSES_PER_NETWORK_MAX 1024U
24 int generate_ipv6_eui_64_address(Link
*link
, struct in6_addr
*ret
) {
28 /* see RFC4291 section 2.5.1 */
29 ret
->s6_addr
[8] = link
->mac
.ether_addr_octet
[0];
30 ret
->s6_addr
[8] ^= 1 << 1;
31 ret
->s6_addr
[9] = link
->mac
.ether_addr_octet
[1];
32 ret
->s6_addr
[10] = link
->mac
.ether_addr_octet
[2];
33 ret
->s6_addr
[11] = 0xff;
34 ret
->s6_addr
[12] = 0xfe;
35 ret
->s6_addr
[13] = link
->mac
.ether_addr_octet
[3];
36 ret
->s6_addr
[14] = link
->mac
.ether_addr_octet
[4];
37 ret
->s6_addr
[15] = link
->mac
.ether_addr_octet
[5];
42 int address_new(Address
**ret
) {
43 _cleanup_(address_freep
) Address
*address
= NULL
;
45 address
= new(Address
, 1);
49 *address
= (Address
) {
51 .scope
= RT_SCOPE_UNIVERSE
,
52 .cinfo
.ifa_prefered
= CACHE_INFO_INFINITY_LIFE_TIME
,
53 .cinfo
.ifa_valid
= CACHE_INFO_INFINITY_LIFE_TIME
,
54 .duplicate_address_detection
= ADDRESS_FAMILY_IPV6
,
58 *ret
= TAKE_PTR(address
);
63 static int address_new_static(Network
*network
, const char *filename
, unsigned section_line
, Address
**ret
) {
64 _cleanup_(network_config_section_freep
) NetworkConfigSection
*n
= NULL
;
65 _cleanup_(address_freep
) Address
*address
= NULL
;
70 assert(!!filename
== (section_line
> 0));
73 r
= network_config_section_new(filename
, section_line
, &n
);
77 address
= hashmap_get(network
->addresses_by_section
, n
);
79 *ret
= TAKE_PTR(address
);
85 if (network
->n_static_addresses
>= STATIC_ADDRESSES_PER_NETWORK_MAX
)
88 r
= address_new(&address
);
92 address
->network
= network
;
93 LIST_APPEND(addresses
, network
->static_addresses
, address
);
94 network
->n_static_addresses
++;
97 address
->section
= TAKE_PTR(n
);
99 r
= hashmap_ensure_allocated(&network
->addresses_by_section
, &network_config_hash_ops
);
103 r
= hashmap_put(network
->addresses_by_section
, address
->section
, address
);
108 *ret
= TAKE_PTR(address
);
113 void address_free(Address
*address
) {
117 if (address
->network
) {
118 LIST_REMOVE(addresses
, address
->network
->static_addresses
, address
);
119 assert(address
->network
->n_static_addresses
> 0);
120 address
->network
->n_static_addresses
--;
122 if (address
->section
)
123 hashmap_remove(address
->network
->addresses_by_section
, address
->section
);
126 if (address
->link
&& !address
->acd
) {
129 set_remove(address
->link
->addresses
, address
);
130 set_remove(address
->link
->addresses_foreign
, address
);
131 set_remove(address
->link
->static_addresses
, address
);
132 if (address
->link
->dhcp_address
== address
)
133 address
->link
->dhcp_address
= NULL
;
134 if (address
->link
->dhcp_address_old
== address
)
135 address
->link
->dhcp_address_old
= NULL
;
136 set_remove(address
->link
->dhcp6_addresses
, address
);
137 set_remove(address
->link
->dhcp6_addresses_old
, address
);
138 set_remove(address
->link
->dhcp6_pd_addresses
, address
);
139 set_remove(address
->link
->dhcp6_pd_addresses_old
, address
);
140 SET_FOREACH(n
, address
->link
->ndisc_addresses
)
141 if (n
->address
== address
)
142 free(set_remove(address
->link
->ndisc_addresses
, n
));
144 if (in_addr_equal(AF_INET6
, &address
->in_addr
, (const union in_addr_union
*) &address
->link
->ipv6ll_address
))
145 memzero(&address
->link
->ipv6ll_address
, sizeof(struct in6_addr
));
148 sd_ipv4acd_unref(address
->acd
);
150 network_config_section_free(address
->section
);
151 free(address
->label
);
155 static uint32_t address_prefix(const Address
*a
) {
158 /* make sure we don't try to shift by 32.
159 * See ISO/IEC 9899:TC3 ยง 6.5.7.3. */
160 if (a
->prefixlen
== 0)
163 if (a
->in_addr_peer
.in
.s_addr
!= 0)
164 return be32toh(a
->in_addr_peer
.in
.s_addr
) >> (32 - a
->prefixlen
);
166 return be32toh(a
->in_addr
.in
.s_addr
) >> (32 - a
->prefixlen
);
169 void address_hash_func(const Address
*a
, struct siphash
*state
) {
172 siphash24_compress(&a
->family
, sizeof(a
->family
), state
);
176 siphash24_compress(&a
->prefixlen
, sizeof(a
->prefixlen
), state
);
179 uint32_t prefix
= address_prefix(a
);
180 siphash24_compress(&prefix
, sizeof(prefix
), state
);
185 siphash24_compress(&a
->in_addr
, FAMILY_ADDRESS_SIZE(a
->family
), state
);
189 /* treat any other address family as AF_UNSPEC */
194 int address_compare_func(const Address
*a1
, const Address
*a2
) {
197 r
= CMP(a1
->family
, a2
->family
);
201 switch (a1
->family
) {
202 /* use the same notion of equality as the kernel does */
204 r
= CMP(a1
->prefixlen
, a2
->prefixlen
);
208 uint32_t prefix1
= address_prefix(a1
);
209 uint32_t prefix2
= address_prefix(a2
);
210 r
= CMP(prefix1
, prefix2
);
216 return memcmp(&a1
->in_addr
, &a2
->in_addr
, FAMILY_ADDRESS_SIZE(a1
->family
));
218 /* treat any other address family as AF_UNSPEC */
223 DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(address_hash_ops
, Address
, address_hash_func
, address_compare_func
, address_free
);
225 bool address_equal(Address
*a1
, Address
*a2
) {
232 return address_compare_func(a1
, a2
) == 0;
235 static int address_establish(Address
*address
, Link
*link
) {
242 masq
= link
->network
&&
243 link
->network
->ip_masquerade
&&
244 address
->family
== AF_INET
&&
245 address
->scope
< RT_SCOPE_LINK
;
247 /* Add firewall entry if this is requested */
248 if (address
->ip_masquerade_done
!= masq
) {
249 union in_addr_union masked
= address
->in_addr
;
250 in_addr_mask(address
->family
, &masked
, address
->prefixlen
);
252 r
= fw_add_masquerade(masq
, AF_INET
, 0, &masked
, address
->prefixlen
, NULL
, NULL
, 0);
256 address
->ip_masquerade_done
= masq
;
262 static int address_add_internal(Link
*link
, Set
**addresses
,
264 const union in_addr_union
*in_addr
,
265 unsigned char prefixlen
,
267 _cleanup_(address_freep
) Address
*address
= NULL
;
274 r
= address_new(&address
);
278 address
->family
= family
;
279 address
->in_addr
= *in_addr
;
280 address
->prefixlen
= prefixlen
;
281 /* Consider address tentative until we get the real flags from the kernel */
282 address
->flags
= IFA_F_TENTATIVE
;
284 r
= set_ensure_put(addresses
, &address_hash_ops
, address
);
290 address
->link
= link
;
298 int address_add_foreign(Link
*link
, int family
, const union in_addr_union
*in_addr
, unsigned char prefixlen
, Address
**ret
) {
299 return address_add_internal(link
, &link
->addresses_foreign
, family
, in_addr
, prefixlen
, ret
);
302 int address_add(Link
*link
, int family
, const union in_addr_union
*in_addr
, unsigned char prefixlen
, Address
**ret
) {
306 r
= address_get(link
, family
, in_addr
, prefixlen
, &address
);
308 /* Address does not exist, create a new one */
309 r
= address_add_internal(link
, &link
->addresses
, family
, in_addr
, prefixlen
, &address
);
313 /* Take over a foreign address */
314 r
= set_ensure_put(&link
->addresses
, &address_hash_ops
, address
);
318 set_remove(link
->addresses_foreign
, address
);
320 /* Already exists, do nothing */
331 static int address_release(Address
*address
) {
335 assert(address
->link
);
337 /* Remove masquerading firewall entry if it was added */
338 if (address
->ip_masquerade_done
) {
339 union in_addr_union masked
= address
->in_addr
;
340 in_addr_mask(address
->family
, &masked
, address
->prefixlen
);
342 r
= fw_add_masquerade(false, AF_INET
, 0, &masked
, address
->prefixlen
, NULL
, NULL
, 0);
346 address
->ip_masquerade_done
= false;
356 const struct ifa_cacheinfo
*cinfo
) {
362 assert(address
->link
);
365 ready
= address_is_ready(address
);
367 address
->flags
= flags
;
368 address
->scope
= scope
;
369 address
->cinfo
= *cinfo
;
371 if (IN_SET(address
->link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
374 link_update_operstate(address
->link
, true);
375 link_check_ready(address
->link
);
377 if (!ready
&& address_is_ready(address
)) {
378 if (address
->callback
) {
379 r
= address
->callback(address
);
384 if (address
->family
== AF_INET6
&&
385 in_addr_is_link_local(AF_INET6
, &address
->in_addr
) > 0 &&
386 IN6_IS_ADDR_UNSPECIFIED(&address
->link
->ipv6ll_address
) > 0) {
388 r
= link_ipv6ll_gained(address
->link
, &address
->in_addr
.in6
);
397 int address_drop(Address
*address
) {
404 ready
= address_is_ready(address
);
405 link
= address
->link
;
407 r
= address_release(address
);
409 log_link_warning_errno(link
, r
, "Failed to disable IP masquerading, ignoring: %m");
411 address_free(address
);
413 link_update_operstate(link
, true);
416 link_check_ready(link
);
421 int address_get(Link
*link
,
423 const union in_addr_union
*in_addr
,
424 unsigned char prefixlen
,
427 Address address
, *existing
;
432 address
= (Address
) {
435 .prefixlen
= prefixlen
,
438 existing
= set_get(link
->addresses
, &address
);
445 existing
= set_get(link
->addresses_foreign
, &address
);
455 static bool address_exists_internal(Set
*addresses
, int family
, const union in_addr_union
*in_addr
) {
458 SET_FOREACH(address
, addresses
) {
459 if (address
->family
!= family
)
461 if (in_addr_equal(address
->family
, &address
->in_addr
, in_addr
))
468 bool address_exists(Link
*link
, int family
, const union in_addr_union
*in_addr
) {
470 assert(IN_SET(family
, AF_INET
, AF_INET6
));
473 if (address_exists_internal(link
->addresses
, family
, in_addr
))
475 if (address_exists_internal(link
->addresses_foreign
, family
, in_addr
))
480 static int address_remove_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Link
*link
) {
485 assert(link
->ifname
);
487 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
490 r
= sd_netlink_message_get_errno(m
);
491 if (r
< 0 && r
!= -EADDRNOTAVAIL
)
492 log_link_message_warning_errno(link
, m
, r
, "Could not drop address");
494 (void) manager_rtnl_process_address(rtnl
, m
, link
->manager
);
502 link_netlink_message_handler_t callback
) {
504 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
;
508 assert(IN_SET(address
->family
, AF_INET
, AF_INET6
));
510 assert(link
->ifindex
> 0);
511 assert(link
->manager
);
512 assert(link
->manager
->rtnl
);
515 _cleanup_free_
char *b
= NULL
;
517 (void) in_addr_to_string(address
->family
, &address
->in_addr
, &b
);
518 log_link_debug(link
, "Removing address %s", strna(b
));
521 r
= sd_rtnl_message_new_addr(link
->manager
->rtnl
, &req
, RTM_DELADDR
,
522 link
->ifindex
, address
->family
);
524 return log_link_error_errno(link
, r
, "Could not allocate RTM_DELADDR message: %m");
526 r
= sd_rtnl_message_addr_set_prefixlen(req
, address
->prefixlen
);
528 return log_link_error_errno(link
, r
, "Could not set prefixlen: %m");
530 r
= netlink_message_append_in_addr_union(req
, IFA_LOCAL
, address
->family
, &address
->in_addr
);
532 return log_link_error_errno(link
, r
, "Could not append IFA_LOCAL attribute: %m");
534 r
= netlink_call_async(link
->manager
->rtnl
, NULL
, req
,
535 callback
?: address_remove_handler
,
536 link_netlink_destroy_callback
, link
);
538 return log_link_error_errno(link
, r
, "Could not send rtnetlink message: %m");
545 static int address_acquire(Link
*link
, Address
*original
, Address
**ret
) {
546 union in_addr_union in_addr
= IN_ADDR_NULL
;
547 struct in_addr broadcast
= {};
548 _cleanup_(address_freep
) Address
*na
= NULL
;
555 /* Something useful was configured? just use it */
556 r
= in_addr_is_null(original
->family
, &original
->in_addr
);
560 /* The address is configured to be 0.0.0.0 or [::] by the user?
561 * Then let's acquire something more useful from the pool. */
562 r
= manager_address_pool_acquire(link
->manager
, original
->family
, original
->prefixlen
, &in_addr
);
568 if (original
->family
== AF_INET
) {
569 /* Pick first address in range for ourselves ... */
570 in_addr
.in
.s_addr
= in_addr
.in
.s_addr
| htobe32(1);
572 /* .. and use last as broadcast address */
573 if (original
->prefixlen
> 30)
574 broadcast
.s_addr
= 0;
576 broadcast
.s_addr
= in_addr
.in
.s_addr
| htobe32(0xFFFFFFFFUL
>> original
->prefixlen
);
577 } else if (original
->family
== AF_INET6
)
578 in_addr
.in6
.s6_addr
[15] |= 1;
580 r
= address_new(&na
);
584 na
->family
= original
->family
;
585 na
->prefixlen
= original
->prefixlen
;
586 na
->scope
= original
->scope
;
587 na
->cinfo
= original
->cinfo
;
589 if (original
->label
) {
590 na
->label
= strdup(original
->label
);
595 na
->broadcast
= broadcast
;
596 na
->in_addr
= in_addr
;
598 LIST_PREPEND(addresses
, link
->pool_addresses
, na
);
605 int address_configure(
608 link_netlink_message_handler_t callback
,
612 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
;
617 assert(IN_SET(address
->family
, AF_INET
, AF_INET6
));
619 assert(link
->ifindex
> 0);
620 assert(link
->manager
);
621 assert(link
->manager
->rtnl
);
624 /* If this is a new address, then refuse adding more than the limit */
625 if (address_get(link
, address
->family
, &address
->in_addr
, address
->prefixlen
, NULL
) <= 0 &&
626 set_size(link
->addresses
) >= ADDRESSES_PER_LINK_MAX
)
627 return log_link_error_errno(link
, SYNTHETIC_ERRNO(E2BIG
),
628 "Too many addresses are configured, refusing: %m");
630 r
= address_acquire(link
, address
, &address
);
632 return log_link_error_errno(link
, r
, "Failed to acquire an address from pool: %m");
635 _cleanup_free_
char *str
= NULL
;
637 (void) in_addr_to_string(address
->family
, &address
->in_addr
, &str
);
638 log_link_debug(link
, "%s address: %s", update
? "Updating" : "Configuring", strna(str
));
642 r
= sd_rtnl_message_new_addr_update(link
->manager
->rtnl
, &req
,
643 link
->ifindex
, address
->family
);
645 r
= sd_rtnl_message_new_addr(link
->manager
->rtnl
, &req
, RTM_NEWADDR
,
646 link
->ifindex
, address
->family
);
648 return log_link_error_errno(link
, r
, "Could not allocate RTM_NEWADDR message: %m");
650 r
= sd_rtnl_message_addr_set_prefixlen(req
, address
->prefixlen
);
652 return log_link_error_errno(link
, r
, "Could not set prefixlen: %m");
654 address
->flags
|= IFA_F_PERMANENT
;
656 if (address
->home_address
)
657 address
->flags
|= IFA_F_HOMEADDRESS
;
659 if (!FLAGS_SET(address
->duplicate_address_detection
, ADDRESS_FAMILY_IPV6
))
660 address
->flags
|= IFA_F_NODAD
;
662 if (address
->manage_temporary_address
)
663 address
->flags
|= IFA_F_MANAGETEMPADDR
;
665 if (!address
->prefix_route
)
666 address
->flags
|= IFA_F_NOPREFIXROUTE
;
668 if (address
->autojoin
)
669 address
->flags
|= IFA_F_MCAUTOJOIN
;
671 r
= sd_rtnl_message_addr_set_flags(req
, (address
->flags
& 0xff));
673 return log_link_error_errno(link
, r
, "Could not set flags: %m");
675 if (address
->flags
& ~0xff) {
676 r
= sd_netlink_message_append_u32(req
, IFA_FLAGS
, address
->flags
);
678 return log_link_error_errno(link
, r
, "Could not set extended flags: %m");
681 r
= sd_rtnl_message_addr_set_scope(req
, address
->scope
);
683 return log_link_error_errno(link
, r
, "Could not set scope: %m");
685 r
= netlink_message_append_in_addr_union(req
, IFA_LOCAL
, address
->family
, &address
->in_addr
);
687 return log_link_error_errno(link
, r
, "Could not append IFA_LOCAL attribute: %m");
689 if (in_addr_is_null(address
->family
, &address
->in_addr_peer
) == 0) {
690 r
= netlink_message_append_in_addr_union(req
, IFA_ADDRESS
, address
->family
, &address
->in_addr_peer
);
692 return log_link_error_errno(link
, r
, "Could not append IFA_ADDRESS attribute: %m");
693 } else if (address
->family
== AF_INET
&& address
->prefixlen
<= 30) {
694 r
= sd_netlink_message_append_in_addr(req
, IFA_BROADCAST
, &address
->broadcast
);
696 return log_link_error_errno(link
, r
, "Could not append IFA_BROADCAST attribute: %m");
699 if (address
->label
) {
700 r
= sd_netlink_message_append_string(req
, IFA_LABEL
, address
->label
);
702 return log_link_error_errno(link
, r
, "Could not append IFA_LABEL attribute: %m");
705 r
= sd_netlink_message_append_cache_info(req
, IFA_CACHEINFO
, &address
->cinfo
);
707 return log_link_error_errno(link
, r
, "Could not append IFA_CACHEINFO attribute: %m");
709 r
= address_establish(address
, link
);
711 log_link_warning_errno(link
, r
, "Could not enable IP masquerading, ignoring: %m");
713 r
= netlink_call_async(link
->manager
->rtnl
, NULL
, req
, callback
, link_netlink_destroy_callback
, link
);
715 address_release(address
);
716 return log_link_error_errno(link
, r
, "Could not send rtnetlink message: %m");
721 if (address
->family
== AF_INET6
&& !in_addr_is_null(address
->family
, &address
->in_addr_peer
))
722 r
= address_add(link
, address
->family
, &address
->in_addr_peer
, address
->prefixlen
, &a
);
724 r
= address_add(link
, address
->family
, &address
->in_addr
, address
->prefixlen
, &a
);
726 address_release(address
);
727 return log_link_error_errno(link
, r
, "Could not add address: %m");
731 assert(address
->family
== AF_INET
);
733 _cleanup_free_
char *pretty
= NULL
;
735 (void) in_addr_to_string(address
->family
, &address
->in_addr
, &pretty
);
736 log_link_debug(link
, "Starting IPv4ACD client. Probing address %s", strna(pretty
));
739 r
= sd_ipv4acd_start(address
->acd
, true);
741 log_link_warning_errno(link
, r
, "Failed to start IPv4ACD client, ignoring: %m");
750 static void static_address_on_acd(sd_ipv4acd
*acd
, int event
, void *userdata
) {
751 _cleanup_free_
char *pretty
= NULL
;
759 address
= (Address
*) userdata
;
760 link
= address
->link
;
762 (void) in_addr_to_string(address
->family
, &address
->in_addr
, &pretty
);
764 case SD_IPV4ACD_EVENT_STOP
:
765 log_link_debug(link
, "Stopping ACD client...");
768 case SD_IPV4ACD_EVENT_BIND
:
769 log_link_debug(link
, "Successfully claimed address %s", strna(pretty
));
770 link_check_ready(link
);
773 case SD_IPV4ACD_EVENT_CONFLICT
:
774 log_link_warning(link
, "DAD conflict. Dropping address %s", strna(pretty
));
775 r
= address_remove(address
, link
, NULL
);
777 log_link_error_errno(link
, r
, "Failed to drop DAD conflicted address %s", strna(pretty
));;
779 link_check_ready(link
);
783 assert_not_reached("Invalid IPv4ACD event.");
786 sd_ipv4acd_stop(acd
);
791 int configure_ipv4_duplicate_address_detection(Link
*link
, Address
*address
) {
796 assert(address
->family
== AF_INET
);
797 assert(!address
->link
&& address
->network
);
799 address
->link
= link
;
801 r
= sd_ipv4acd_new(&address
->acd
);
805 r
= sd_ipv4acd_attach_event(address
->acd
, NULL
, 0);
809 r
= sd_ipv4acd_set_ifindex(address
->acd
, link
->ifindex
);
813 r
= sd_ipv4acd_set_mac(address
->acd
, &link
->mac
);
817 r
= sd_ipv4acd_set_address(address
->acd
, &address
->in_addr
.in
);
821 r
= sd_ipv4acd_set_callback(address
->acd
, static_address_on_acd
, address
);
828 int config_parse_broadcast(
830 const char *filename
,
833 unsigned section_line
,
840 Network
*network
= userdata
;
841 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
850 r
= address_new_static(network
, filename
, section_line
, &n
);
854 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
855 "Failed to allocate new address, ignoring assignment: %m");
859 if (n
->family
== AF_INET6
) {
860 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
861 "Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue
);
865 r
= in_addr_from_string(AF_INET
, rvalue
, (union in_addr_union
*) &n
->broadcast
);
867 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
868 "Broadcast is invalid, ignoring assignment: %s", rvalue
);
878 int config_parse_address(const char *unit
,
879 const char *filename
,
882 unsigned section_line
,
889 Network
*network
= userdata
;
890 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
891 union in_addr_union buffer
;
892 unsigned char prefixlen
;
901 if (streq(section
, "Network")) {
902 /* we are not in an Address section, so treat
903 * this as the special '0' section */
904 r
= address_new_static(network
, NULL
, 0, &n
);
906 r
= address_new_static(network
, filename
, section_line
, &n
);
910 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
911 "Failed to allocate new address, ignoring assignment: %m");
915 /* Address=address/prefixlen */
916 r
= in_addr_prefix_from_string_auto_internal(rvalue
, PREFIXLEN_REFUSE
, &f
, &buffer
, &prefixlen
);
918 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
919 "An address '%s' is specified without prefix length. "
920 "The behavior of parsing addresses without prefix length will be changed in the future release. "
921 "Please specify prefix length explicitly.", rvalue
);
923 r
= in_addr_prefix_from_string_auto_internal(rvalue
, PREFIXLEN_LEGACY
, &f
, &buffer
, &prefixlen
);
926 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
, "Invalid address '%s', ignoring assignment: %m", rvalue
);
930 if (n
->family
!= AF_UNSPEC
&& f
!= n
->family
) {
931 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0, "Address is incompatible, ignoring assignment: %s", rvalue
);
935 if (in_addr_is_null(f
, &buffer
)) {
936 /* Will use address from address pool. Note that for ipv6 case, prefix of the address
937 * pool is 8, but 40 bit is used by the global ID and 16 bit by the subnet ID. So,
938 * let's limit the prefix length to 64 or larger. See RFC4193. */
939 if ((f
== AF_INET
&& prefixlen
< 8) ||
940 (f
== AF_INET6
&& prefixlen
< 64)) {
941 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
942 "Null address with invalid prefixlen='%u', ignoring assignment: %s",
949 n
->prefixlen
= prefixlen
;
951 if (streq(lvalue
, "Address"))
954 n
->in_addr_peer
= buffer
;
956 if (n
->family
== AF_INET
&& n
->broadcast
.s_addr
== 0 && n
->prefixlen
<= 30)
957 n
->broadcast
.s_addr
= n
->in_addr
.in
.s_addr
| htobe32(0xfffffffflu
>> n
->prefixlen
);
964 int config_parse_label(
966 const char *filename
,
969 unsigned section_line
,
976 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
977 Network
*network
= userdata
;
986 r
= address_new_static(network
, filename
, section_line
, &n
);
990 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
991 "Failed to allocate new address, ignoring assignment: %m");
995 if (!address_label_valid(rvalue
)) {
996 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
997 "Interface label is too long or invalid, ignoring assignment: %s", rvalue
);
1001 r
= free_and_strdup(&n
->label
, rvalue
);
1009 int config_parse_lifetime(const char *unit
,
1010 const char *filename
,
1012 const char *section
,
1013 unsigned section_line
,
1019 Network
*network
= userdata
;
1020 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
1030 r
= address_new_static(network
, filename
, section_line
, &n
);
1034 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1035 "Failed to allocate new address, ignoring assignment: %m");
1039 /* We accept only "forever", "infinity", empty, or "0". */
1040 if (STR_IN_SET(rvalue
, "forever", "infinity", ""))
1041 k
= CACHE_INFO_INFINITY_LIFE_TIME
;
1042 else if (streq(rvalue
, "0"))
1045 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1046 "Invalid PreferredLifetime= value, ignoring: %s", rvalue
);
1050 n
->cinfo
.ifa_prefered
= k
;
1056 int config_parse_address_flags(const char *unit
,
1057 const char *filename
,
1059 const char *section
,
1060 unsigned section_line
,
1066 Network
*network
= userdata
;
1067 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
1076 r
= address_new_static(network
, filename
, section_line
, &n
);
1080 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1081 "Failed to allocate new address, ignoring assignment: %m");
1085 r
= parse_boolean(rvalue
);
1087 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1088 "Failed to parse %s=, ignoring: %s", lvalue
, rvalue
);
1092 if (streq(lvalue
, "HomeAddress"))
1093 n
->home_address
= r
;
1094 else if (streq(lvalue
, "ManageTemporaryAddress"))
1095 n
->manage_temporary_address
= r
;
1096 else if (streq(lvalue
, "PrefixRoute"))
1097 n
->prefix_route
= !r
;
1098 else if (streq(lvalue
, "AddPrefixRoute"))
1099 n
->prefix_route
= r
;
1100 else if (streq(lvalue
, "AutoJoin"))
1103 assert_not_reached("Invalid address flag type.");
1109 int config_parse_address_scope(const char *unit
,
1110 const char *filename
,
1112 const char *section
,
1113 unsigned section_line
,
1119 Network
*network
= userdata
;
1120 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
1129 r
= address_new_static(network
, filename
, section_line
, &n
);
1133 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1134 "Failed to allocate new address, ignoring assignment: %m");
1138 if (streq(rvalue
, "host"))
1139 n
->scope
= RT_SCOPE_HOST
;
1140 else if (streq(rvalue
, "link"))
1141 n
->scope
= RT_SCOPE_LINK
;
1142 else if (streq(rvalue
, "global"))
1143 n
->scope
= RT_SCOPE_UNIVERSE
;
1145 r
= safe_atou8(rvalue
, &n
->scope
);
1147 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1148 "Could not parse address scope \"%s\", ignoring assignment: %m", rvalue
);
1153 n
->scope_set
= true;
1158 int config_parse_duplicate_address_detection(
1160 const char *filename
,
1162 const char *section
,
1163 unsigned section_line
,
1169 Network
*network
= userdata
;
1170 _cleanup_(address_free_or_set_invalidp
) Address
*n
= NULL
;
1180 r
= address_new_static(network
, filename
, section_line
, &n
);
1184 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1185 "Failed to allocate new address, ignoring assignment: %m");
1189 r
= parse_boolean(rvalue
);
1191 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1192 "For historical reasons, %s=%s means %s=%s. "
1193 "Please use 'both', 'ipv4', 'ipv6' or 'none' instead.",
1194 lvalue
, rvalue
, lvalue
, r
? "none" : "both");
1195 n
->duplicate_address_detection
= r
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_YES
;
1200 a
= duplicate_address_detection_address_family_from_string(rvalue
);
1202 log_syntax(unit
, LOG_WARNING
, filename
, line
, SYNTHETIC_ERRNO(EINVAL
),
1203 "Failed to parse %s=, ignoring: %s", lvalue
, rvalue
);
1207 n
->duplicate_address_detection
= a
;
1212 bool address_is_ready(const Address
*a
) {
1215 return !(a
->flags
& IFA_F_TENTATIVE
);
1218 int address_section_verify(Address
*address
) {
1219 if (section_is_invalid(address
->section
))
1222 if (address
->family
== AF_UNSPEC
) {
1223 assert(address
->section
);
1225 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
1226 "%s: Address section without Address= field configured. "
1227 "Ignoring [Address] section from line %u.",
1228 address
->section
->filename
, address
->section
->line
);
1231 if (!address
->scope_set
&& in_addr_is_localhost(address
->family
, &address
->in_addr
) > 0)
1232 address
->scope
= RT_SCOPE_HOST
;