1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include <linux/netdevice.h>
5 #include "alloc-util.h"
6 #include "conf-files.h"
7 #include "conf-parser.h"
8 #include "dns-domain.h"
10 #include "hostname-util.h"
11 #include "in-addr-util.h"
12 #include "network-internal.h"
13 #include "networkd-manager.h"
14 #include "networkd-network.h"
15 #include "parse-util.h"
17 #include "socket-util.h"
18 #include "stat-util.h"
19 #include "string-table.h"
20 #include "string-util.h"
24 /* Let's assume that anything above this number is a user misconfiguration. */
25 #define MAX_NTP_SERVERS 128
27 /* Set defaults following RFC7844 */
28 void network_apply_anonymize_if_set(Network
*network
) {
29 if (!network
->dhcp_anonymize
)
32 SHOULD NOT send the Host Name option */
33 network
->dhcp_send_hostname
= false;
34 /* RFC7844 section 3.:
35 MAY contain the Client Identifier option
37 clients MUST use client identifiers based solely
38 on the link-layer address */
39 /* NOTE: Using MAC, as it does not reveal extra information,
40 * and some servers might not answer if this option is not sent */
41 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
43 SHOULD NOT use the Vendor Class Identifier option */
44 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
45 /* RFC7844 section 3.6.:
46 The client intending to protect its privacy SHOULD only request a
47 minimal number of options in the PRL and SHOULD also randomly shuffle
48 the ordering of option codes in the PRL. If this random ordering
49 cannot be implemented, the client MAY order the option codes in the
50 PRL by option code number (lowest to highest).
52 /* NOTE: dhcp_use_mtu is false by default,
53 * though it was not initiallized to any value in network_load_one.
54 * Maybe there should be another var called *send*?
55 * (to use the MTU sent by the server but to do not send
56 * the option in the PRL). */
57 network
->dhcp_use_mtu
= false;
58 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
59 * but this is needed to use them. */
60 network
->dhcp_use_routes
= true;
61 /* RFC7844 section 3.6.
62 * same comments as previous option */
63 network
->dhcp_use_timezone
= false;
66 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
67 const char *kind_string
;
71 /* For test-networkd-conf, the check must be earlier than the assertions. */
76 assert(network
->manager
);
77 assert(network
->filename
);
80 if (kind
== _NETDEV_KIND_TUNNEL
)
81 kind_string
= "tunnel";
83 kind_string
= netdev_kind_to_string(kind
);
85 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
86 "%s: Invalid NetDev kind of %s, ignoring assignment.",
87 network
->filename
, name
);
90 r
= netdev_get(network
->manager
, name
, &netdev
);
92 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
93 network
->filename
, name
);
95 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
102 NETDEV_KIND_IP6GRETAP
,
106 NETDEV_KIND_ERSPAN
)))
107 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
108 "%s: NetDev %s is not a %s, ignoring assignment",
109 network
->filename
, name
, kind_string
);
111 *ret_netdev
= netdev_ref(netdev
);
115 static int network_resolve_stacked_netdevs(Network
*network
) {
122 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
123 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
125 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
129 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
133 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
135 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
136 network
->filename
, (const char *) name
);
144 static uint32_t network_get_stacked_netdevs_mtu(Network
*network
) {
149 HASHMAP_FOREACH(dev
, network
->stacked_netdevs
, i
)
150 if (dev
->kind
== NETDEV_KIND_VLAN
&& dev
->mtu
> 0)
151 /* See vlan_dev_change_mtu() in kernel.
152 * Note that the additional 4bytes may not be necessary for all devices. */
153 mtu
= MAX(mtu
, dev
->mtu
+ 4);
155 else if (dev
->kind
== NETDEV_KIND_MACVLAN
&& dev
->mtu
> mtu
)
156 /* See macvlan_change_mtu() in kernel. */
162 int network_verify(Network
*network
) {
163 Address
*address
, *address_next
;
164 Route
*route
, *route_next
;
165 FdbEntry
*fdb
, *fdb_next
;
166 Neighbor
*neighbor
, *neighbor_next
;
167 AddressLabel
*label
, *label_next
;
168 Prefix
*prefix
, *prefix_next
;
169 RoutingPolicyRule
*rule
, *rule_next
;
173 assert(network
->filename
);
175 if (set_isempty(network
->match_mac
) && strv_isempty(network
->match_path
) &&
176 strv_isempty(network
->match_driver
) && strv_isempty(network
->match_type
) &&
177 strv_isempty(network
->match_name
) && !network
->conditions
)
178 log_warning("%s: No valid settings found in the [Match] section. "
179 "The file will match all interfaces. "
180 "If that is intended, please add Name=* in the [Match] section.",
183 /* skip out early if configuration does not match the environment */
184 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
185 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
186 "%s: Conditions in the file do not match the system environment, skipping.",
189 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
190 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
191 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
192 (void) network_resolve_stacked_netdevs(network
);
194 /* Free unnecessary entries. */
195 network
->bond_name
= mfree(network
->bond_name
);
196 network
->bridge_name
= mfree(network
->bridge_name
);
197 network
->vrf_name
= mfree(network
->vrf_name
);
198 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
201 /* Bonding slave does not support addressing. */
202 if (network
->ipv6_accept_ra
> 0) {
203 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
205 network
->ipv6_accept_ra
= 0;
207 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
208 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
210 network
->link_local
= ADDRESS_FAMILY_NO
;
212 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
213 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
215 network
->dhcp
= ADDRESS_FAMILY_NO
;
217 if (network
->dhcp_server
) {
218 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
220 network
->dhcp_server
= false;
222 if (network
->n_static_addresses
> 0) {
223 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
225 while ((address
= network
->static_addresses
))
226 address_free(address
);
228 if (network
->n_static_routes
> 0) {
229 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
231 while ((route
= network
->static_routes
))
236 if (network
->link_local
< 0)
237 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
239 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
240 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
241 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
242 "Disabling the fallback assignment.", network
->filename
);
243 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
246 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
247 network
->ipv6_accept_ra
= false;
249 /* IPMasquerade=yes implies IPForward=yes */
250 if (network
->ip_masquerade
)
251 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
253 network
->mtu_is_set
= network
->mtu
> 0;
254 mtu
= network_get_stacked_netdevs_mtu(network
);
255 if (network
->mtu
< mtu
) {
256 if (network
->mtu_is_set
)
257 log_notice("%s: Bumping MTUBytes= from %"PRIu32
" to %"PRIu32
" because of stacked device",
258 network
->filename
, network
->mtu
, mtu
);
262 if (network
->mtu_is_set
&& network
->dhcp_use_mtu
) {
263 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
264 "Disabling UseMTU=.", network
->filename
);
265 network
->dhcp_use_mtu
= false;
268 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
269 if (address_section_verify(address
) < 0)
270 address_free(address
);
272 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
273 if (route_section_verify(route
, network
) < 0)
276 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
277 if (section_is_invalid(fdb
->section
))
280 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
281 if (section_is_invalid(neighbor
->section
))
282 neighbor_free(neighbor
);
284 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
285 if (section_is_invalid(label
->section
))
286 address_label_free(label
);
288 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
289 if (section_is_invalid(prefix
->section
))
292 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
293 if (section_is_invalid(rule
->section
))
294 routing_policy_rule_free(rule
);
299 int network_load_one(Manager
*manager
, const char *filename
) {
300 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
301 _cleanup_(network_unrefp
) Network
*network
= NULL
;
302 _cleanup_fclose_
FILE *file
= NULL
;
303 const char *dropin_dirname
;
310 file
= fopen(filename
, "re");
318 if (null_or_empty_fd(fileno(file
))) {
319 log_debug("Skipping empty file: %s", filename
);
323 fname
= strdup(filename
);
327 name
= strdup(basename(filename
));
331 d
= strrchr(name
, '.');
337 dropin_dirname
= strjoina(name
, ".network.d");
339 network
= new(Network
, 1);
343 *network
= (Network
) {
344 .filename
= TAKE_PTR(fname
),
345 .name
= TAKE_PTR(name
),
350 .required_for_online
= true,
351 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
352 .dhcp
= ADDRESS_FAMILY_NO
,
353 .dhcp_use_ntp
= true,
354 .dhcp_use_dns
= true,
355 .dhcp_use_hostname
= true,
356 .dhcp_use_routes
= true,
357 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
358 .dhcp_send_hostname
= true,
359 /* To enable/disable RFC7844 Anonymity Profiles */
360 .dhcp_anonymize
= false,
361 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
362 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
363 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
364 .dhcp_route_table
= RT_TABLE_MAIN
,
365 .dhcp_route_table_set
= false,
366 /* NOTE: from man: UseMTU=... Defaults to false*/
367 .dhcp_use_mtu
= false,
368 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
369 .dhcp_use_timezone
= false,
370 .rapid_commit
= true,
372 .dhcp_server_emit_dns
= true,
373 .dhcp_server_emit_ntp
= true,
374 .dhcp_server_emit_router
= true,
375 .dhcp_server_emit_timezone
= true,
377 .router_emit_dns
= true,
378 .router_emit_domains
= true,
383 .allow_port_to_be_root
= -1,
385 .multicast_flood
= -1,
386 .multicast_to_unicast
= -1,
387 .neighbor_suppression
= -1,
389 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
391 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
393 .dns_default_route
= -1,
394 .llmnr
= RESOLVE_SUPPORT_YES
,
395 .mdns
= RESOLVE_SUPPORT_NO
,
396 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
397 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
399 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
400 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
402 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
403 .ipv6_accept_ra
= -1,
404 .ipv6_dad_transmits
= -1,
405 .ipv6_hop_limit
= -1,
406 .ipv6_proxy_ndp
= -1,
407 .duid
.type
= _DUID_TYPE_INVALID
,
412 .ipv6_accept_ra_use_dns
= true,
413 .ipv6_accept_ra_use_autonomous_prefix
= true,
414 .ipv6_accept_ra_use_onlink_prefix
= true,
415 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
416 .ipv6_accept_ra_route_table_set
= false,
418 .can_triple_sampling
= -1,
421 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
428 "RoutingPolicyRule\0"
431 "DHCPv4\0" /* compat */
434 "IPv6NDPProxyAddress\0"
438 "IPv6PrefixDelegation\0"
441 config_item_perf_lookup
, network_network_gperf_lookup
,
442 CONFIG_PARSE_WARN
, network
);
446 network_apply_anonymize_if_set(network
);
448 r
= network_add_ipv4ll_route(network
);
450 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
452 r
= ordered_hashmap_ensure_allocated(&manager
->networks
, &string_hash_ops
);
456 r
= ordered_hashmap_put(manager
->networks
, network
->name
, network
);
460 if (network_verify(network
) < 0)
467 int network_load(Manager
*manager
) {
468 _cleanup_strv_free_
char **files
= NULL
;
474 ordered_hashmap_clear_with_destructor(manager
->networks
, network_unref
);
476 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
478 return log_error_errno(r
, "Failed to enumerate network files: %m");
480 STRV_FOREACH(f
, files
) {
481 r
= network_load_one(manager
, *f
);
489 static Network
*network_free(Network
*network
) {
490 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
491 RoutingPolicyRule
*rule
;
502 free(network
->filename
);
504 set_free_free(network
->match_mac
);
505 strv_free(network
->match_path
);
506 strv_free(network
->match_driver
);
507 strv_free(network
->match_type
);
508 strv_free(network
->match_name
);
509 condition_free_list(network
->conditions
);
511 free(network
->description
);
512 free(network
->dhcp_vendor_class_identifier
);
513 strv_free(network
->dhcp_user_class
);
514 free(network
->dhcp_hostname
);
518 strv_free(network
->ntp
);
520 ordered_set_free_free(network
->search_domains
);
521 ordered_set_free_free(network
->route_domains
);
522 strv_free(network
->bind_carrier
);
524 ordered_set_free_free(network
->router_search_domains
);
525 free(network
->router_dns
);
527 free(network
->bridge_name
);
528 free(network
->bond_name
);
529 free(network
->vrf_name
);
530 hashmap_free_free_key(network
->stacked_netdev_names
);
531 netdev_unref(network
->bridge
);
532 netdev_unref(network
->bond
);
533 netdev_unref(network
->vrf
);
534 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
536 while ((route
= network
->static_routes
))
539 while ((address
= network
->static_addresses
))
540 address_free(address
);
542 while ((fdb_entry
= network
->static_fdb_entries
))
543 fdb_entry_free(fdb_entry
);
545 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
546 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
548 while ((neighbor
= network
->neighbors
))
549 neighbor_free(neighbor
);
551 while ((label
= network
->address_labels
))
552 address_label_free(label
);
554 while ((prefix
= network
->static_prefixes
))
557 while ((rule
= network
->rules
))
558 routing_policy_rule_free(rule
);
560 hashmap_free(network
->addresses_by_section
);
561 hashmap_free(network
->routes_by_section
);
562 hashmap_free(network
->fdb_entries_by_section
);
563 hashmap_free(network
->neighbors_by_section
);
564 hashmap_free(network
->address_labels_by_section
);
565 hashmap_free(network
->prefixes_by_section
);
566 hashmap_free(network
->rules_by_section
);
568 if (network
->manager
) {
569 if (network
->manager
->networks
&& network
->name
)
570 ordered_hashmap_remove(network
->manager
->networks
, network
->name
);
572 if (network
->manager
->duids_requesting_uuid
)
573 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
578 free(network
->dhcp_server_timezone
);
579 free(network
->dhcp_server_dns
);
580 free(network
->dhcp_server_ntp
);
582 set_free_free(network
->dnssec_negative_trust_anchors
);
584 return mfree(network
);
587 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
589 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
596 network
= ordered_hashmap_get(manager
->networks
, name
);
605 int network_get(Manager
*manager
, sd_device
*device
,
606 const char *ifname
, const struct ether_addr
*address
,
608 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
616 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
618 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
620 (void) sd_device_get_devtype(device
, &devtype
);
623 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
624 if (net_match_config(network
->match_mac
, network
->match_path
,
625 network
->match_driver
, network
->match_type
,
627 address
, path
, driver
, devtype
, ifname
)) {
628 if (network
->match_name
&& device
) {
630 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
632 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
633 (void) safe_atou8(attr
, &name_assign_type
);
635 if (name_assign_type
== NET_NAME_ENUM
)
636 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
637 ifname
, network
->filename
);
639 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
641 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
652 int network_apply(Network
*network
, Link
*link
) {
656 link
->network
= network_ref(network
);
658 if (network
->n_dns
> 0 ||
659 !strv_isempty(network
->ntp
) ||
660 !ordered_set_isempty(network
->search_domains
) ||
661 !ordered_set_isempty(network
->route_domains
))
667 bool network_has_static_ipv6_addresses(Network
*network
) {
672 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
673 if (address
->family
== AF_INET6
)
680 int config_parse_stacked_netdev(const char *unit
,
681 const char *filename
,
684 unsigned section_line
,
690 _cleanup_free_
char *name
= NULL
;
691 NetDevKind kind
= ltype
;
700 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
701 NETDEV_KIND_IPVLAN
, NETDEV_KIND_VXLAN
, NETDEV_KIND_L2TP
,
702 NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
));
704 if (!ifname_valid(rvalue
)) {
705 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
706 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
710 name
= strdup(rvalue
);
714 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
718 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
720 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
721 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
723 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
724 "NetDev '%s' specified twice, ignoring.", name
);
731 int config_parse_domains(
733 const char *filename
,
736 unsigned section_line
,
751 if (isempty(rvalue
)) {
752 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
753 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
759 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
763 r
= extract_first_word(&p
, &w
, NULL
, 0);
765 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
766 "Failed to extract search or route domain, ignoring: %s", rvalue
);
772 is_route
= w
[0] == '~';
773 domain
= is_route
? w
+ 1 : w
;
775 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
776 /* If the root domain appears as is, or the special token "*" is found, we'll
777 * consider this as routing domain, unconditionally. */
779 domain
= "."; /* make sure we don't allow empty strings, thus write the root
782 r
= dns_name_normalize(domain
, 0, &normalized
);
784 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
785 "'%s' is not a valid domain name, ignoring.", domain
);
791 if (is_localhost(domain
)) {
792 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
793 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
799 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
800 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
804 r
= ordered_set_put_strdup(*set
, domain
);
812 int config_parse_ipv4ll(
814 const char *filename
,
817 unsigned section_line
,
824 AddressFamilyBoolean
*link_local
= data
;
832 /* Note that this is mostly like
833 * config_parse_address_family_boolean(), except that it
834 * applies only to IPv4 */
836 r
= parse_boolean(rvalue
);
838 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
839 "Failed to parse %s=%s, ignoring assignment. "
840 "Note that the setting %s= is deprecated, please use LinkLocalAddressing= instead.",
841 lvalue
, rvalue
, lvalue
);
845 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, r
);
847 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
848 "%s=%s is deprecated, please use LinkLocalAddressing=%s instead.",
849 lvalue
, rvalue
, address_family_boolean_to_string(*link_local
));
854 int config_parse_dhcp(
856 const char *filename
,
859 unsigned section_line
,
866 AddressFamilyBoolean
*dhcp
= data
, s
;
873 /* Note that this is mostly like
874 * config_parse_address_family_boolean(), except that it
875 * understands some old names for the enum values */
877 s
= address_family_boolean_from_string(rvalue
);
880 /* Previously, we had a slightly different enum here,
881 * support its values for compatibility. */
883 if (streq(rvalue
, "none"))
884 s
= ADDRESS_FAMILY_NO
;
885 else if (streq(rvalue
, "v4"))
886 s
= ADDRESS_FAMILY_IPV4
;
887 else if (streq(rvalue
, "v6"))
888 s
= ADDRESS_FAMILY_IPV6
;
889 else if (streq(rvalue
, "both"))
890 s
= ADDRESS_FAMILY_YES
;
892 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
893 "Failed to parse DHCP option, ignoring: %s", rvalue
);
897 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
898 "DHCP=%s is deprecated, please use DHCP=%s instead.",
899 rvalue
, address_family_boolean_to_string(s
));
906 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
907 [DHCP_CLIENT_ID_MAC
] = "mac",
908 [DHCP_CLIENT_ID_DUID
] = "duid",
909 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
912 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
913 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
914 "Failed to parse client identifier type");
916 int config_parse_ipv6token(
918 const char *filename
,
921 unsigned section_line
,
928 union in_addr_union buffer
;
929 struct in6_addr
*token
= data
;
937 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
939 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
940 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
944 if (in_addr_is_null(AF_INET6
, &buffer
)) {
945 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
946 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
950 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
951 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
952 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
961 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
962 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
963 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
964 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
967 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
969 int config_parse_ipv6_privacy_extensions(
971 const char *filename
,
974 unsigned section_line
,
981 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
987 assert(ipv6_privacy_extensions
);
989 /* Our enum shall be a superset of booleans, hence first try
990 * to parse as boolean, and then as enum */
992 k
= parse_boolean(rvalue
);
994 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
996 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
998 IPv6PrivacyExtensions s
;
1000 s
= ipv6_privacy_extensions_from_string(rvalue
);
1003 if (streq(rvalue
, "kernel"))
1004 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1006 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1007 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1012 *ipv6_privacy_extensions
= s
;
1018 int config_parse_hostname(
1020 const char *filename
,
1022 const char *section
,
1023 unsigned section_line
,
1030 _cleanup_free_
char *hn
= NULL
;
1031 char **hostname
= data
;
1038 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1042 if (!hostname_is_valid(hn
, false)) {
1043 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1044 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1048 r
= dns_name_is_valid(hn
);
1050 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1051 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1055 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1056 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1060 return free_and_replace(*hostname
, hn
);
1063 int config_parse_timezone(
1065 const char *filename
,
1067 const char *section
,
1068 unsigned section_line
,
1075 _cleanup_free_
char *tz
= NULL
;
1076 char **datap
= data
;
1083 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1087 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1088 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1089 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1093 return free_and_replace(*datap
, tz
);
1096 int config_parse_dhcp_server_dns(
1098 const char *filename
,
1100 const char *section
,
1101 unsigned section_line
,
1109 const char *p
= rvalue
;
1117 _cleanup_free_
char *w
= NULL
;
1118 struct in_addr a
, *m
;
1120 r
= extract_first_word(&p
, &w
, NULL
, 0);
1124 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1125 "Failed to extract word, ignoring: %s", rvalue
);
1131 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1132 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1133 "Failed to parse DNS server address, ignoring: %s", w
);
1137 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1141 m
[n
->n_dhcp_server_dns
++] = a
;
1142 n
->dhcp_server_dns
= m
;
1148 int config_parse_radv_dns(
1150 const char *filename
,
1152 const char *section
,
1153 unsigned section_line
,
1161 const char *p
= rvalue
;
1169 _cleanup_free_
char *w
= NULL
;
1170 union in_addr_union a
;
1172 r
= extract_first_word(&p
, &w
, NULL
, 0);
1176 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1177 "Failed to extract word, ignoring: %s", rvalue
);
1183 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1186 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1190 m
[n
->n_router_dns
++] = a
.in6
;
1194 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1195 "Failed to parse DNS server address, ignoring: %s", w
);
1201 int config_parse_radv_search_domains(
1203 const char *filename
,
1205 const char *section
,
1206 unsigned section_line
,
1214 const char *p
= rvalue
;
1222 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1224 r
= extract_first_word(&p
, &w
, NULL
, 0);
1228 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1229 "Failed to extract word, ignoring: %s", rvalue
);
1235 r
= dns_name_apply_idna(w
, &idna
);
1237 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1238 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1241 /* transfer ownership to simplify subsequent operations */
1244 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1248 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1256 int config_parse_dhcp_server_ntp(
1258 const char *filename
,
1260 const char *section
,
1261 unsigned section_line
,
1269 const char *p
= rvalue
;
1277 _cleanup_free_
char *w
= NULL
;
1278 struct in_addr a
, *m
;
1280 r
= extract_first_word(&p
, &w
, NULL
, 0);
1284 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1285 "Failed to extract word, ignoring: %s", rvalue
);
1291 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1292 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1293 "Failed to parse NTP server address, ignoring: %s", w
);
1297 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1301 m
[n
->n_dhcp_server_ntp
++] = a
;
1302 n
->dhcp_server_ntp
= m
;
1306 int config_parse_dns(
1308 const char *filename
,
1310 const char *section
,
1311 unsigned section_line
,
1318 Network
*n
= userdata
;
1326 _cleanup_free_
char *w
= NULL
;
1327 union in_addr_union a
;
1328 struct in_addr_data
*m
;
1331 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1335 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1336 "Invalid syntax, ignoring: %s", rvalue
);
1342 r
= in_addr_from_string_auto(w
, &family
, &a
);
1344 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1345 "Failed to parse dns server address, ignoring: %s", w
);
1349 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1353 m
[n
->n_dns
++] = (struct in_addr_data
) {
1364 int config_parse_dnssec_negative_trust_anchors(
1366 const char *filename
,
1368 const char *section
,
1369 unsigned section_line
,
1376 const char *p
= rvalue
;
1384 if (isempty(rvalue
)) {
1385 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1390 _cleanup_free_
char *w
= NULL
;
1392 r
= extract_first_word(&p
, &w
, NULL
, 0);
1394 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1395 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1401 r
= dns_name_is_valid(w
);
1403 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1404 "%s is not a valid domain name, ignoring.", w
);
1408 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1412 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1422 int config_parse_ntp(
1424 const char *filename
,
1426 const char *section
,
1427 unsigned section_line
,
1441 if (isempty(rvalue
)) {
1447 _cleanup_free_
char *w
= NULL
;
1449 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1453 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1454 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1460 r
= dns_name_is_valid_or_address(w
);
1462 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1463 "%s is not a valid domain name or IP address, ignoring.", w
);
1467 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1468 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1469 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1470 MAX_NTP_SERVERS
, w
);
1474 r
= strv_consume(l
, TAKE_PTR(w
));
1482 int config_parse_dhcp_user_class(
1484 const char *filename
,
1486 const char *section
,
1487 unsigned section_line
,
1501 if (isempty(rvalue
)) {
1507 _cleanup_free_
char *w
= NULL
;
1509 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1513 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1514 "Failed to split user classes option, ignoring: %s", rvalue
);
1520 if (strlen(w
) > 255) {
1521 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1522 "%s length is not in the range 1-255, ignoring.", w
);
1526 r
= strv_push(l
, w
);
1536 int config_parse_section_route_table(
1538 const char *filename
,
1540 const char *section
,
1541 unsigned section_line
,
1548 Network
*network
= data
;
1557 r
= safe_atou32(rvalue
, &rt
);
1559 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1560 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1564 if (streq_ptr(section
, "DHCP")) {
1565 network
->dhcp_route_table
= rt
;
1566 network
->dhcp_route_table_set
= true;
1567 } else { /* section is IPv6AcceptRA */
1568 network
->ipv6_accept_ra_route_table
= rt
;
1569 network
->ipv6_accept_ra_route_table_set
= true;
1575 int config_parse_dhcp_max_attempts(
1577 const char *filename
,
1579 const char *section
,
1580 unsigned section_line
,
1587 Network
*network
= data
;
1595 if (isempty(rvalue
)) {
1596 network
->dhcp_max_attempts
= 0;
1600 if (streq(rvalue
, "infinity")) {
1601 network
->dhcp_max_attempts
= (uint64_t) -1;
1605 r
= safe_atou64(rvalue
, &a
);
1607 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1608 "Failed to parse DHCP maximum attempts, ignoring: %s", rvalue
);
1613 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1614 "%s= must be positive integer or 'infinity', ignoring: %s", lvalue
, rvalue
);
1618 network
->dhcp_max_attempts
= a
;
1623 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1624 "Failed to parse DHCP use domains setting");
1626 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1627 [DHCP_USE_DOMAINS_NO
] = "no",
1628 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1629 [DHCP_USE_DOMAINS_YES
] = "yes",
1632 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1634 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1636 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1637 [LLDP_MODE_NO
] = "no",
1638 [LLDP_MODE_YES
] = "yes",
1639 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1642 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
1644 int config_parse_iaid(const char *unit
,
1645 const char *filename
,
1647 const char *section
,
1648 unsigned section_line
,
1654 Network
*network
= data
;
1663 r
= safe_atou32(rvalue
, &iaid
);
1665 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1666 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1670 network
->iaid
= iaid
;
1671 network
->iaid_set
= true;
1676 int config_parse_required_for_online(
1678 const char *filename
,
1680 const char *section
,
1681 unsigned section_line
,
1688 Network
*network
= data
;
1689 LinkOperationalState s
;
1690 bool required
= true;
1693 if (isempty(rvalue
)) {
1694 network
->required_for_online
= true;
1695 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1699 s
= link_operstate_from_string(rvalue
);
1701 r
= parse_boolean(rvalue
);
1703 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1704 "Failed to parse %s= setting, ignoring assignment: %s",
1710 s
= LINK_OPERSTATE_DEGRADED
;
1713 network
->required_for_online
= required
;
1714 network
->required_operstate_for_online
= s
;