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
),
349 .required_for_online
= true,
350 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
351 .dhcp
= ADDRESS_FAMILY_NO
,
352 .dhcp_use_ntp
= true,
353 .dhcp_use_dns
= true,
354 .dhcp_use_hostname
= true,
355 .dhcp_use_routes
= true,
356 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
357 .dhcp_send_hostname
= true,
358 /* To enable/disable RFC7844 Anonymity Profiles */
359 .dhcp_anonymize
= false,
360 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
361 /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
362 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
363 .dhcp_route_table
= RT_TABLE_MAIN
,
364 .dhcp_route_table_set
= false,
365 /* NOTE: from man: UseMTU=... Defaults to false*/
366 .dhcp_use_mtu
= false,
367 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
368 .dhcp_use_timezone
= false,
369 .rapid_commit
= true,
371 .dhcp_server_emit_dns
= true,
372 .dhcp_server_emit_ntp
= true,
373 .dhcp_server_emit_router
= true,
374 .dhcp_server_emit_timezone
= true,
376 .router_emit_dns
= true,
377 .router_emit_domains
= true,
382 .allow_port_to_be_root
= -1,
384 .multicast_flood
= -1,
385 .multicast_to_unicast
= -1,
386 .neighbor_suppression
= -1,
388 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
390 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
392 .dns_default_route
= -1,
393 .llmnr
= RESOLVE_SUPPORT_YES
,
394 .mdns
= RESOLVE_SUPPORT_NO
,
395 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
396 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
398 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
399 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
401 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
402 .ipv6_accept_ra
= -1,
403 .ipv6_dad_transmits
= -1,
404 .ipv6_hop_limit
= -1,
405 .ipv6_proxy_ndp
= -1,
406 .duid
.type
= _DUID_TYPE_INVALID
,
411 .ipv6_accept_ra_use_dns
= true,
412 .ipv6_accept_ra_use_autonomous_prefix
= true,
413 .ipv6_accept_ra_use_onlink_prefix
= true,
414 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
415 .ipv6_accept_ra_route_table_set
= false,
417 .can_triple_sampling
= -1,
420 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
427 "RoutingPolicyRule\0"
430 "DHCPv4\0" /* compat */
433 "IPv6NDPProxyAddress\0"
437 "IPv6PrefixDelegation\0"
440 config_item_perf_lookup
, network_network_gperf_lookup
,
441 CONFIG_PARSE_WARN
, network
);
445 network_apply_anonymize_if_set(network
);
447 r
= network_add_ipv4ll_route(network
);
449 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
451 LIST_PREPEND(networks
, manager
->networks
, network
);
452 network
->manager
= manager
;
454 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
458 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
462 if (network_verify(network
) < 0)
469 int network_load(Manager
*manager
) {
471 _cleanup_strv_free_
char **files
= NULL
;
477 while ((network
= manager
->networks
))
478 network_unref(network
);
480 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
482 return log_error_errno(r
, "Failed to enumerate network files: %m");
484 STRV_FOREACH_BACKWARDS(f
, files
) {
485 r
= network_load_one(manager
, *f
);
493 static Network
*network_free(Network
*network
) {
494 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
495 RoutingPolicyRule
*rule
;
506 free(network
->filename
);
508 set_free_free(network
->match_mac
);
509 strv_free(network
->match_path
);
510 strv_free(network
->match_driver
);
511 strv_free(network
->match_type
);
512 strv_free(network
->match_name
);
513 condition_free_list(network
->conditions
);
515 free(network
->description
);
516 free(network
->dhcp_vendor_class_identifier
);
517 strv_free(network
->dhcp_user_class
);
518 free(network
->dhcp_hostname
);
522 strv_free(network
->ntp
);
524 ordered_set_free_free(network
->search_domains
);
525 ordered_set_free_free(network
->route_domains
);
526 strv_free(network
->bind_carrier
);
528 ordered_set_free_free(network
->router_search_domains
);
529 free(network
->router_dns
);
531 free(network
->bridge_name
);
532 free(network
->bond_name
);
533 free(network
->vrf_name
);
534 hashmap_free_free_key(network
->stacked_netdev_names
);
535 netdev_unref(network
->bridge
);
536 netdev_unref(network
->bond
);
537 netdev_unref(network
->vrf
);
538 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
540 while ((route
= network
->static_routes
))
543 while ((address
= network
->static_addresses
))
544 address_free(address
);
546 while ((fdb_entry
= network
->static_fdb_entries
))
547 fdb_entry_free(fdb_entry
);
549 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
550 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
552 while ((neighbor
= network
->neighbors
))
553 neighbor_free(neighbor
);
555 while ((label
= network
->address_labels
))
556 address_label_free(label
);
558 while ((prefix
= network
->static_prefixes
))
561 while ((rule
= network
->rules
))
562 routing_policy_rule_free(rule
);
564 hashmap_free(network
->addresses_by_section
);
565 hashmap_free(network
->routes_by_section
);
566 hashmap_free(network
->fdb_entries_by_section
);
567 hashmap_free(network
->neighbors_by_section
);
568 hashmap_free(network
->address_labels_by_section
);
569 hashmap_free(network
->prefixes_by_section
);
570 hashmap_free(network
->rules_by_section
);
572 if (network
->manager
) {
573 if (network
->manager
->networks
)
574 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
576 if (network
->manager
->networks_by_name
&& network
->name
)
577 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
579 if (network
->manager
->duids_requesting_uuid
)
580 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
585 free(network
->dhcp_server_timezone
);
586 free(network
->dhcp_server_dns
);
587 free(network
->dhcp_server_ntp
);
589 set_free_free(network
->dnssec_negative_trust_anchors
);
591 return mfree(network
);
594 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
596 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
603 network
= hashmap_get(manager
->networks_by_name
, name
);
612 int network_get(Manager
*manager
, sd_device
*device
,
613 const char *ifname
, const struct ether_addr
*address
,
615 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
622 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
624 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
626 (void) sd_device_get_devtype(device
, &devtype
);
629 LIST_FOREACH(networks
, network
, manager
->networks
) {
630 if (net_match_config(network
->match_mac
, network
->match_path
,
631 network
->match_driver
, network
->match_type
,
633 address
, path
, driver
, devtype
, ifname
)) {
634 if (network
->match_name
&& device
) {
636 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
638 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
639 (void) safe_atou8(attr
, &name_assign_type
);
641 if (name_assign_type
== NET_NAME_ENUM
)
642 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
643 ifname
, network
->filename
);
645 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
647 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
659 int network_apply(Network
*network
, Link
*link
) {
663 link
->network
= network
;
665 if (network
->n_dns
> 0 ||
666 !strv_isempty(network
->ntp
) ||
667 !ordered_set_isempty(network
->search_domains
) ||
668 !ordered_set_isempty(network
->route_domains
))
674 bool network_has_static_ipv6_addresses(Network
*network
) {
679 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
680 if (address
->family
== AF_INET6
)
687 int config_parse_stacked_netdev(const char *unit
,
688 const char *filename
,
691 unsigned section_line
,
697 _cleanup_free_
char *name
= NULL
;
698 NetDevKind kind
= ltype
;
707 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
708 NETDEV_KIND_IPVLAN
, NETDEV_KIND_VXLAN
, NETDEV_KIND_L2TP
,
709 NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
));
711 if (!ifname_valid(rvalue
)) {
712 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
713 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
717 name
= strdup(rvalue
);
721 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
725 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
727 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
728 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
730 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
731 "NetDev '%s' specified twice, ignoring.", name
);
738 int config_parse_domains(
740 const char *filename
,
743 unsigned section_line
,
758 if (isempty(rvalue
)) {
759 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
760 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
766 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
770 r
= extract_first_word(&p
, &w
, NULL
, 0);
772 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
773 "Failed to extract search or route domain, ignoring: %s", rvalue
);
779 is_route
= w
[0] == '~';
780 domain
= is_route
? w
+ 1 : w
;
782 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
783 /* If the root domain appears as is, or the special token "*" is found, we'll
784 * consider this as routing domain, unconditionally. */
786 domain
= "."; /* make sure we don't allow empty strings, thus write the root
789 r
= dns_name_normalize(domain
, 0, &normalized
);
791 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
792 "'%s' is not a valid domain name, ignoring.", domain
);
798 if (is_localhost(domain
)) {
799 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
800 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
806 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
807 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
811 r
= ordered_set_put_strdup(*set
, domain
);
819 int config_parse_ipv4ll(
821 const char *filename
,
824 unsigned section_line
,
831 AddressFamilyBoolean
*link_local
= data
;
839 /* Note that this is mostly like
840 * config_parse_address_family_boolean(), except that it
841 * applies only to IPv4 */
843 r
= parse_boolean(rvalue
);
845 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
846 "Failed to parse %s=%s, ignoring assignment. "
847 "Note that the setting %s= is deprecated, please use LinkLocalAddressing= instead.",
848 lvalue
, rvalue
, lvalue
);
852 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, r
);
854 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
855 "%s=%s is deprecated, please use LinkLocalAddressing=%s instead.",
856 lvalue
, rvalue
, address_family_boolean_to_string(*link_local
));
861 int config_parse_dhcp(
863 const char *filename
,
866 unsigned section_line
,
873 AddressFamilyBoolean
*dhcp
= data
, s
;
880 /* Note that this is mostly like
881 * config_parse_address_family_boolean(), except that it
882 * understands some old names for the enum values */
884 s
= address_family_boolean_from_string(rvalue
);
887 /* Previously, we had a slightly different enum here,
888 * support its values for compatibility. */
890 if (streq(rvalue
, "none"))
891 s
= ADDRESS_FAMILY_NO
;
892 else if (streq(rvalue
, "v4"))
893 s
= ADDRESS_FAMILY_IPV4
;
894 else if (streq(rvalue
, "v6"))
895 s
= ADDRESS_FAMILY_IPV6
;
896 else if (streq(rvalue
, "both"))
897 s
= ADDRESS_FAMILY_YES
;
899 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
900 "Failed to parse DHCP option, ignoring: %s", rvalue
);
904 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
905 "DHCP=%s is deprecated, please use DHCP=%s instead.",
906 rvalue
, address_family_boolean_to_string(s
));
913 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
914 [DHCP_CLIENT_ID_MAC
] = "mac",
915 [DHCP_CLIENT_ID_DUID
] = "duid",
916 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
919 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
920 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
921 "Failed to parse client identifier type");
923 int config_parse_ipv6token(
925 const char *filename
,
928 unsigned section_line
,
935 union in_addr_union buffer
;
936 struct in6_addr
*token
= data
;
944 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
946 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
947 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
951 if (in_addr_is_null(AF_INET6
, &buffer
)) {
952 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
953 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
957 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
958 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
959 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
968 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
969 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
970 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
971 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
974 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
976 int config_parse_ipv6_privacy_extensions(
978 const char *filename
,
981 unsigned section_line
,
988 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
994 assert(ipv6_privacy_extensions
);
996 /* Our enum shall be a superset of booleans, hence first try
997 * to parse as boolean, and then as enum */
999 k
= parse_boolean(rvalue
);
1001 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
1003 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
1005 IPv6PrivacyExtensions s
;
1007 s
= ipv6_privacy_extensions_from_string(rvalue
);
1010 if (streq(rvalue
, "kernel"))
1011 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1013 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1014 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1019 *ipv6_privacy_extensions
= s
;
1025 int config_parse_hostname(
1027 const char *filename
,
1029 const char *section
,
1030 unsigned section_line
,
1037 _cleanup_free_
char *hn
= NULL
;
1038 char **hostname
= data
;
1045 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1049 if (!hostname_is_valid(hn
, false)) {
1050 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1051 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1055 r
= dns_name_is_valid(hn
);
1057 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1058 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1062 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1063 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1067 return free_and_replace(*hostname
, hn
);
1070 int config_parse_timezone(
1072 const char *filename
,
1074 const char *section
,
1075 unsigned section_line
,
1082 _cleanup_free_
char *tz
= NULL
;
1083 char **datap
= data
;
1090 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1094 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1095 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1096 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1100 return free_and_replace(*datap
, tz
);
1103 int config_parse_dhcp_server_dns(
1105 const char *filename
,
1107 const char *section
,
1108 unsigned section_line
,
1116 const char *p
= rvalue
;
1124 _cleanup_free_
char *w
= NULL
;
1125 struct in_addr a
, *m
;
1127 r
= extract_first_word(&p
, &w
, NULL
, 0);
1131 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1132 "Failed to extract word, ignoring: %s", rvalue
);
1138 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1139 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1140 "Failed to parse DNS server address, ignoring: %s", w
);
1144 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1148 m
[n
->n_dhcp_server_dns
++] = a
;
1149 n
->dhcp_server_dns
= m
;
1155 int config_parse_radv_dns(
1157 const char *filename
,
1159 const char *section
,
1160 unsigned section_line
,
1168 const char *p
= rvalue
;
1176 _cleanup_free_
char *w
= NULL
;
1177 union in_addr_union a
;
1179 r
= extract_first_word(&p
, &w
, NULL
, 0);
1183 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1184 "Failed to extract word, ignoring: %s", rvalue
);
1190 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1193 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1197 m
[n
->n_router_dns
++] = a
.in6
;
1201 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1202 "Failed to parse DNS server address, ignoring: %s", w
);
1208 int config_parse_radv_search_domains(
1210 const char *filename
,
1212 const char *section
,
1213 unsigned section_line
,
1221 const char *p
= rvalue
;
1229 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1231 r
= extract_first_word(&p
, &w
, NULL
, 0);
1235 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1236 "Failed to extract word, ignoring: %s", rvalue
);
1242 r
= dns_name_apply_idna(w
, &idna
);
1244 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1245 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1248 /* transfer ownership to simplify subsequent operations */
1251 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1255 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1263 int config_parse_dhcp_server_ntp(
1265 const char *filename
,
1267 const char *section
,
1268 unsigned section_line
,
1276 const char *p
= rvalue
;
1284 _cleanup_free_
char *w
= NULL
;
1285 struct in_addr a
, *m
;
1287 r
= extract_first_word(&p
, &w
, NULL
, 0);
1291 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1292 "Failed to extract word, ignoring: %s", rvalue
);
1298 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1299 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1300 "Failed to parse NTP server address, ignoring: %s", w
);
1304 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1308 m
[n
->n_dhcp_server_ntp
++] = a
;
1309 n
->dhcp_server_ntp
= m
;
1313 int config_parse_dns(
1315 const char *filename
,
1317 const char *section
,
1318 unsigned section_line
,
1325 Network
*n
= userdata
;
1333 _cleanup_free_
char *w
= NULL
;
1334 union in_addr_union a
;
1335 struct in_addr_data
*m
;
1338 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1342 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1343 "Invalid syntax, ignoring: %s", rvalue
);
1349 r
= in_addr_from_string_auto(w
, &family
, &a
);
1351 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1352 "Failed to parse dns server address, ignoring: %s", w
);
1356 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1360 m
[n
->n_dns
++] = (struct in_addr_data
) {
1371 int config_parse_dnssec_negative_trust_anchors(
1373 const char *filename
,
1375 const char *section
,
1376 unsigned section_line
,
1383 const char *p
= rvalue
;
1391 if (isempty(rvalue
)) {
1392 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1397 _cleanup_free_
char *w
= NULL
;
1399 r
= extract_first_word(&p
, &w
, NULL
, 0);
1401 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1402 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1408 r
= dns_name_is_valid(w
);
1410 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1411 "%s is not a valid domain name, ignoring.", w
);
1415 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1419 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1429 int config_parse_ntp(
1431 const char *filename
,
1433 const char *section
,
1434 unsigned section_line
,
1448 if (isempty(rvalue
)) {
1454 _cleanup_free_
char *w
= NULL
;
1456 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1460 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1461 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1467 r
= dns_name_is_valid_or_address(w
);
1469 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1470 "%s is not a valid domain name or IP address, ignoring.", w
);
1474 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1475 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1476 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1477 MAX_NTP_SERVERS
, w
);
1481 r
= strv_consume(l
, TAKE_PTR(w
));
1489 int config_parse_dhcp_user_class(
1491 const char *filename
,
1493 const char *section
,
1494 unsigned section_line
,
1508 if (isempty(rvalue
)) {
1514 _cleanup_free_
char *w
= NULL
;
1516 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1520 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1521 "Failed to split user classes option, ignoring: %s", rvalue
);
1527 if (strlen(w
) > 255) {
1528 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1529 "%s length is not in the range 1-255, ignoring.", w
);
1533 r
= strv_push(l
, w
);
1543 int config_parse_section_route_table(
1545 const char *filename
,
1547 const char *section
,
1548 unsigned section_line
,
1555 Network
*network
= data
;
1564 r
= safe_atou32(rvalue
, &rt
);
1566 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1567 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1571 if (streq_ptr(section
, "DHCP")) {
1572 network
->dhcp_route_table
= rt
;
1573 network
->dhcp_route_table_set
= true;
1574 } else { /* section is IPv6AcceptRA */
1575 network
->ipv6_accept_ra_route_table
= rt
;
1576 network
->ipv6_accept_ra_route_table_set
= true;
1582 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1583 "Failed to parse DHCP use domains setting");
1585 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1586 [DHCP_USE_DOMAINS_NO
] = "no",
1587 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1588 [DHCP_USE_DOMAINS_YES
] = "yes",
1591 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1593 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1595 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1596 [LLDP_MODE_NO
] = "no",
1597 [LLDP_MODE_YES
] = "yes",
1598 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1601 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
1603 int config_parse_iaid(const char *unit
,
1604 const char *filename
,
1606 const char *section
,
1607 unsigned section_line
,
1613 Network
*network
= data
;
1622 r
= safe_atou32(rvalue
, &iaid
);
1624 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1625 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1629 network
->iaid
= iaid
;
1630 network
->iaid_set
= true;
1635 int config_parse_required_for_online(
1637 const char *filename
,
1639 const char *section
,
1640 unsigned section_line
,
1647 Network
*network
= data
;
1648 LinkOperationalState s
;
1649 bool required
= true;
1652 if (isempty(rvalue
)) {
1653 network
->required_for_online
= true;
1654 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1658 s
= link_operstate_from_string(rvalue
);
1660 r
= parse_boolean(rvalue
);
1662 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1663 "Failed to parse %s= setting, ignoring assignment: %s",
1669 s
= LINK_OPERSTATE_DEGRADED
;
1672 network
->required_for_online
= required
;
1673 network
->required_operstate_for_online
= s
;