1 /* SPDX-License-Identifier: LGPL-2.1+ */
6 #include "alloc-util.h"
7 #include "conf-files.h"
8 #include "conf-parser.h"
9 #include "dns-domain.h"
11 #include "hostname-util.h"
12 #include "in-addr-util.h"
13 #include "missing_network.h"
14 #include "network-internal.h"
15 #include "networkd-manager.h"
16 #include "networkd-network.h"
17 #include "parse-util.h"
19 #include "stat-util.h"
20 #include "string-table.h"
21 #include "string-util.h"
25 static void network_config_hash_func(const NetworkConfigSection
*c
, struct siphash
*state
) {
26 siphash24_compress(c
->filename
, strlen(c
->filename
), state
);
27 siphash24_compress(&c
->line
, sizeof(c
->line
), state
);
30 static int network_config_compare_func(const NetworkConfigSection
*x
, const NetworkConfigSection
*y
) {
33 r
= strcmp(x
->filename
, y
->filename
);
37 return CMP(x
->line
, y
->line
);
40 DEFINE_HASH_OPS(network_config_hash_ops
, NetworkConfigSection
, network_config_hash_func
, network_config_compare_func
);
42 int network_config_section_new(const char *filename
, unsigned line
, NetworkConfigSection
**s
) {
43 NetworkConfigSection
*cs
;
45 cs
= malloc0(offsetof(NetworkConfigSection
, filename
) + strlen(filename
) + 1);
49 strcpy(cs
->filename
, filename
);
57 void network_config_section_free(NetworkConfigSection
*cs
) {
61 /* Set defaults following RFC7844 */
62 void network_apply_anonymize_if_set(Network
*network
) {
63 if (!network
->dhcp_anonymize
)
66 SHOULD NOT send the Host Name option */
67 network
->dhcp_send_hostname
= false;
68 /* RFC7844 section 3.:
69 MAY contain the Client Identifier option
71 clients MUST use client identifiers based solely
72 on the link-layer address */
73 /* NOTE: Using MAC, as it does not reveal extra information,
74 * and some servers might not answer if this option is not sent */
75 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
77 SHOULD NOT use the Vendor Class Identifier option */
78 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
79 /* RFC7844 section 3.6.:
80 The client intending to protect its privacy SHOULD only request a
81 minimal number of options in the PRL and SHOULD also randomly shuffle
82 the ordering of option codes in the PRL. If this random ordering
83 cannot be implemented, the client MAY order the option codes in the
84 PRL by option code number (lowest to highest).
86 /* NOTE: dhcp_use_mtu is false by default,
87 * though it was not initiallized to any value in network_load_one.
88 * Maybe there should be another var called *send*?
89 * (to use the MTU sent by the server but to do not send
90 * the option in the PRL). */
91 network
->dhcp_use_mtu
= false;
92 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
93 * but this is needed to use them. */
94 network
->dhcp_use_routes
= true;
95 /* RFC7844 section 3.6.
96 * same comments as previous option */
97 network
->dhcp_use_timezone
= false;
100 int network_load_one(Manager
*manager
, const char *filename
) {
101 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
102 _cleanup_(network_freep
) Network
*network
= NULL
;
103 _cleanup_fclose_
FILE *file
= NULL
;
104 const char *dropin_dirname
;
113 file
= fopen(filename
, "re");
121 if (null_or_empty_fd(fileno(file
))) {
122 log_debug("Skipping empty file: %s", filename
);
126 fname
= strdup(filename
);
130 name
= strdup(basename(filename
));
134 d
= strrchr(name
, '.');
140 dropin_dirname
= strjoina(name
, ".network.d");
142 network
= new(Network
, 1);
146 *network
= (Network
) {
148 .filename
= TAKE_PTR(fname
),
149 .name
= TAKE_PTR(name
),
151 .required_for_online
= true,
152 .dhcp
= ADDRESS_FAMILY_NO
,
153 .dhcp_use_ntp
= true,
154 .dhcp_use_dns
= true,
155 .dhcp_use_hostname
= true,
156 .dhcp_use_routes
= true,
157 /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
158 .dhcp_send_hostname
= true,
159 /* To enable/disable RFC7844 Anonymity Profiles */
160 .dhcp_anonymize
= false,
161 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
162 /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
163 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
164 .dhcp_route_table
= RT_TABLE_MAIN
,
165 .dhcp_route_table_set
= false,
166 /* NOTE: from man: UseMTU=... Defaults to false*/
167 .dhcp_use_mtu
= false,
168 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
169 .dhcp_use_timezone
= false,
170 .rapid_commit
= true,
172 .dhcp_server_emit_dns
= true,
173 .dhcp_server_emit_ntp
= true,
174 .dhcp_server_emit_router
= true,
175 .dhcp_server_emit_timezone
= true,
177 .router_emit_dns
= true,
178 .router_emit_domains
= true,
183 .allow_port_to_be_root
= -1,
185 .multicast_to_unicast
= -1,
186 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
188 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
190 .dns_default_route
= -1,
191 .llmnr
= RESOLVE_SUPPORT_YES
,
192 .mdns
= RESOLVE_SUPPORT_NO
,
193 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
194 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
196 .link_local
= ADDRESS_FAMILY_IPV6
,
198 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
199 .ipv6_accept_ra
= -1,
200 .ipv6_dad_transmits
= -1,
201 .ipv6_hop_limit
= -1,
202 .ipv6_proxy_ndp
= -1,
203 .duid
.type
= _DUID_TYPE_INVALID
,
208 .ipv6_accept_ra_use_dns
= true,
209 .ipv6_accept_ra_use_autonomous_prefix
= true,
210 .ipv6_accept_ra_use_onlink_prefix
= true,
211 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
212 .ipv6_accept_ra_route_table_set
= false,
215 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
222 "RoutingPolicyRule\0"
225 "DHCPv4\0" /* compat */
228 "IPv6NDPProxyAddress\0"
232 "IPv6PrefixDelegation\0"
235 config_item_perf_lookup
, network_network_gperf_lookup
,
236 CONFIG_PARSE_WARN
, network
);
238 /* Unset manager here. Otherwise, LIST_REMOVE() in network_free() fails. */
239 network
->manager
= NULL
;
243 network_apply_anonymize_if_set(network
);
245 /* IPMasquerade=yes implies IPForward=yes */
246 if (network
->ip_masquerade
)
247 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
249 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
250 log_warning("MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set in %s. "
251 "Disabling UseMTU=.", filename
);
252 network
->dhcp_use_mtu
= false;
255 LIST_PREPEND(networks
, manager
->networks
, network
);
257 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
261 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
265 LIST_FOREACH(routes
, route
, network
->static_routes
)
266 if (!route
->family
) {
267 log_warning("Route section without Gateway field configured in %s. "
268 "Ignoring", filename
);
272 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
273 if (!address
->family
) {
274 log_warning("Address section without Address field configured in %s. "
275 "Ignoring", filename
);
284 int network_load(Manager
*manager
) {
286 _cleanup_strv_free_
char **files
= NULL
;
292 while ((network
= manager
->networks
))
293 network_free(network
);
295 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
297 return log_error_errno(r
, "Failed to enumerate network files: %m");
299 STRV_FOREACH_BACKWARDS(f
, files
) {
300 r
= network_load_one(manager
, *f
);
308 void network_free(Network
*network
) {
309 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
310 RoutingPolicyRule
*rule
;
321 free(network
->filename
);
323 set_free_free(network
->match_mac
);
324 strv_free(network
->match_path
);
325 strv_free(network
->match_driver
);
326 strv_free(network
->match_type
);
327 strv_free(network
->match_name
);
329 free(network
->description
);
330 free(network
->dhcp_vendor_class_identifier
);
331 strv_free(network
->dhcp_user_class
);
332 free(network
->dhcp_hostname
);
336 strv_free(network
->ntp
);
338 strv_free(network
->search_domains
);
339 strv_free(network
->route_domains
);
340 strv_free(network
->bind_carrier
);
342 strv_free(network
->router_search_domains
);
343 free(network
->router_dns
);
345 netdev_unref(network
->bridge
);
346 netdev_unref(network
->bond
);
347 netdev_unref(network
->vrf
);
349 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
351 while ((route
= network
->static_routes
))
354 while ((address
= network
->static_addresses
))
355 address_free(address
);
357 while ((fdb_entry
= network
->static_fdb_entries
))
358 fdb_entry_free(fdb_entry
);
360 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
361 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
363 while ((neighbor
= network
->neighbors
))
364 neighbor_free(neighbor
);
366 while ((label
= network
->address_labels
))
367 address_label_free(label
);
369 while ((prefix
= network
->static_prefixes
))
372 while ((rule
= network
->rules
))
373 routing_policy_rule_free(rule
);
375 hashmap_free(network
->addresses_by_section
);
376 hashmap_free(network
->routes_by_section
);
377 hashmap_free(network
->fdb_entries_by_section
);
378 hashmap_free(network
->neighbors_by_section
);
379 hashmap_free(network
->address_labels_by_section
);
380 hashmap_free(network
->prefixes_by_section
);
381 hashmap_free(network
->rules_by_section
);
383 if (network
->manager
) {
384 if (network
->manager
->networks
)
385 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
387 if (network
->manager
->networks_by_name
&& network
->name
)
388 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
390 if (network
->manager
->duids_requesting_uuid
)
391 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
396 condition_free_list(network
->match_host
);
397 condition_free_list(network
->match_virt
);
398 condition_free_list(network
->match_kernel_cmdline
);
399 condition_free_list(network
->match_kernel_version
);
400 condition_free_list(network
->match_arch
);
402 free(network
->dhcp_server_timezone
);
403 free(network
->dhcp_server_dns
);
404 free(network
->dhcp_server_ntp
);
406 set_free_free(network
->dnssec_negative_trust_anchors
);
411 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
418 network
= hashmap_get(manager
->networks_by_name
, name
);
427 int network_get(Manager
*manager
, sd_device
*device
,
428 const char *ifname
, const struct ether_addr
*address
,
430 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
437 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
439 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
441 (void) sd_device_get_devtype(device
, &devtype
);
444 LIST_FOREACH(networks
, network
, manager
->networks
) {
445 if (net_match_config(network
->match_mac
, network
->match_path
,
446 network
->match_driver
, network
->match_type
,
447 network
->match_name
, network
->match_host
,
448 network
->match_virt
, network
->match_kernel_cmdline
,
449 network
->match_kernel_version
, network
->match_arch
,
450 address
, path
, driver
, devtype
, ifname
)) {
451 if (network
->match_name
&& device
) {
453 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
455 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
456 (void) safe_atou8(attr
, &name_assign_type
);
458 if (name_assign_type
== NET_NAME_ENUM
)
459 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
460 ifname
, network
->filename
);
462 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
464 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
476 int network_apply(Network
*network
, Link
*link
) {
482 link
->network
= network
;
484 if (network
->ipv4ll_route
) {
487 r
= route_new_static(network
, NULL
, 0, &route
);
491 r
= inet_pton(AF_INET
, "169.254.0.0", &route
->dst
.in
);
497 route
->family
= AF_INET
;
498 route
->dst_prefixlen
= 16;
499 route
->scope
= RT_SCOPE_LINK
;
500 route
->priority
= IPV4LL_ROUTE_METRIC
;
501 route
->protocol
= RTPROT_STATIC
;
504 if (network
->n_dns
> 0 ||
505 !strv_isempty(network
->ntp
) ||
506 !strv_isempty(network
->search_domains
) ||
507 !strv_isempty(network
->route_domains
))
513 bool network_has_static_ipv6_addresses(Network
*network
) {
518 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
519 if (address
->family
== AF_INET6
)
526 int config_parse_netdev(const char *unit
,
527 const char *filename
,
530 unsigned section_line
,
536 Network
*network
= userdata
;
537 _cleanup_free_
char *kind_string
= NULL
;
548 kind_string
= strdup(lvalue
);
552 /* the keys are CamelCase versions of the kind */
553 for (p
= kind_string
; *p
; p
++)
556 kind
= netdev_kind_from_string(kind_string
);
557 if (kind
== _NETDEV_KIND_INVALID
) {
558 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Invalid NetDev kind: %s", lvalue
);
562 r
= netdev_get(network
->manager
, rvalue
, &netdev
);
564 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s could not be found, ignoring assignment: %s", lvalue
, rvalue
);
568 if (netdev
->kind
!= kind
) {
569 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "NetDev is not a %s, ignoring assignment: %s", lvalue
, rvalue
);
574 case NETDEV_KIND_BRIDGE
:
575 network
->bridge
= netdev_unref(network
->bridge
);
576 network
->bridge
= netdev
;
579 case NETDEV_KIND_BOND
:
580 network
->bond
= netdev_unref(network
->bond
);
581 network
->bond
= netdev
;
584 case NETDEV_KIND_VRF
:
585 network
->vrf
= netdev_unref(network
->vrf
);
586 network
->vrf
= netdev
;
589 case NETDEV_KIND_VLAN
:
590 case NETDEV_KIND_MACVLAN
:
591 case NETDEV_KIND_MACVTAP
:
592 case NETDEV_KIND_IPVLAN
:
593 case NETDEV_KIND_VXLAN
:
594 case NETDEV_KIND_VCAN
:
595 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
599 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
601 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Cannot add NetDev '%s' to network: %m", rvalue
);
607 assert_not_reached("Cannot parse NetDev");
615 int config_parse_domains(
617 const char *filename
,
620 unsigned section_line
,
635 if (isempty(rvalue
)) {
636 n
->search_domains
= strv_free(n
->search_domains
);
637 n
->route_domains
= strv_free(n
->route_domains
);
643 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
647 r
= extract_first_word(&p
, &w
, NULL
, 0);
649 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract search or route domain, ignoring: %s", rvalue
);
655 is_route
= w
[0] == '~';
656 domain
= is_route
? w
+ 1 : w
;
658 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
659 /* If the root domain appears as is, or the special token "*" is found, we'll consider this as
660 * routing domain, unconditionally. */
662 domain
= "."; /* make sure we don't allow empty strings, thus write the root domain as "." */
664 r
= dns_name_normalize(domain
, 0, &normalized
);
666 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "'%s' is not a valid domain name, ignoring.", domain
);
672 if (is_localhost(domain
)) {
673 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "'localhost' domain names may not be configure as search or route domains, ignoring assignment: %s", domain
);
679 r
= strv_extend(&n
->route_domains
, domain
);
681 r
= strv_extend(&n
->search_domains
, domain
);
686 strv_uniq(n
->route_domains
);
687 strv_uniq(n
->search_domains
);
692 int config_parse_tunnel(const char *unit
,
693 const char *filename
,
696 unsigned section_line
,
702 Network
*network
= userdata
;
711 r
= netdev_get(network
->manager
, rvalue
, &netdev
);
713 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Tunnel is invalid, ignoring assignment: %s", rvalue
);
717 if (!IN_SET(netdev
->kind
,
723 NETDEV_KIND_IP6GRETAP
,
726 NETDEV_KIND_IP6TNL
)) {
727 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
728 "NetDev is not a tunnel, ignoring assignment: %s", rvalue
);
732 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
736 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
738 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Cannot add VLAN '%s' to network, ignoring: %m", rvalue
);
747 int config_parse_ipv4ll(
749 const char *filename
,
752 unsigned section_line
,
759 AddressFamilyBoolean
*link_local
= data
;
766 /* Note that this is mostly like
767 * config_parse_address_family_boolean(), except that it
768 * applies only to IPv4 */
770 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, parse_boolean(rvalue
));
775 int config_parse_dhcp(
777 const char *filename
,
780 unsigned section_line
,
787 AddressFamilyBoolean
*dhcp
= data
, s
;
794 /* Note that this is mostly like
795 * config_parse_address_family_boolean(), except that it
796 * understands some old names for the enum values */
798 s
= address_family_boolean_from_string(rvalue
);
801 /* Previously, we had a slightly different enum here,
802 * support its values for compatbility. */
804 if (streq(rvalue
, "none"))
805 s
= ADDRESS_FAMILY_NO
;
806 else if (streq(rvalue
, "v4"))
807 s
= ADDRESS_FAMILY_IPV4
;
808 else if (streq(rvalue
, "v6"))
809 s
= ADDRESS_FAMILY_IPV6
;
810 else if (streq(rvalue
, "both"))
811 s
= ADDRESS_FAMILY_YES
;
813 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DHCP option, ignoring: %s", rvalue
);
817 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
818 "DHCP=%s is deprecated, please use DHCP=%s instead.",
819 rvalue
, address_family_boolean_to_string(s
));
826 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
827 [DHCP_CLIENT_ID_MAC
] = "mac",
828 [DHCP_CLIENT_ID_DUID
] = "duid",
829 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
832 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
833 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
, "Failed to parse client identifier type");
835 int config_parse_ipv6token(
837 const char *filename
,
840 unsigned section_line
,
847 union in_addr_union buffer
;
848 struct in6_addr
*token
= data
;
856 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
858 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse IPv6 token, ignoring: %s", rvalue
);
862 if (in_addr_is_null(AF_INET6
, &buffer
)) {
863 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
867 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
868 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
877 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
878 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
879 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
880 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
883 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
885 int config_parse_ipv6_privacy_extensions(
887 const char *filename
,
890 unsigned section_line
,
897 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
903 assert(ipv6_privacy_extensions
);
905 /* Our enum shall be a superset of booleans, hence first try
906 * to parse as boolean, and then as enum */
908 k
= parse_boolean(rvalue
);
910 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
912 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
914 IPv6PrivacyExtensions s
;
916 s
= ipv6_privacy_extensions_from_string(rvalue
);
919 if (streq(rvalue
, "kernel"))
920 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
922 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
927 *ipv6_privacy_extensions
= s
;
933 int config_parse_hostname(
935 const char *filename
,
938 unsigned section_line
,
945 _cleanup_free_
char *hn
= NULL
;
946 char **hostname
= data
;
953 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
957 if (!hostname_is_valid(hn
, false)) {
958 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Hostname is not valid, ignoring assignment: %s", rvalue
);
962 r
= dns_name_is_valid(hn
);
964 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
968 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
972 return free_and_replace(*hostname
, hn
);
975 int config_parse_timezone(
977 const char *filename
,
980 unsigned section_line
,
987 _cleanup_free_
char *tz
= NULL
;
995 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
999 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1000 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Timezone is not valid, ignoring assignment: %s", rvalue
);
1004 return free_and_replace(*datap
, tz
);
1007 int config_parse_dhcp_server_dns(
1009 const char *filename
,
1011 const char *section
,
1012 unsigned section_line
,
1020 const char *p
= rvalue
;
1028 _cleanup_free_
char *w
= NULL
;
1029 struct in_addr a
, *m
;
1031 r
= extract_first_word(&p
, &w
, NULL
, 0);
1035 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1041 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1042 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DNS server address, ignoring: %s", w
);
1046 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1050 m
[n
->n_dhcp_server_dns
++] = a
;
1051 n
->dhcp_server_dns
= m
;
1057 int config_parse_radv_dns(
1059 const char *filename
,
1061 const char *section
,
1062 unsigned section_line
,
1070 const char *p
= rvalue
;
1078 _cleanup_free_
char *w
= NULL
;
1079 union in_addr_union a
;
1081 r
= extract_first_word(&p
, &w
, NULL
, 0);
1085 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1091 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1094 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1098 m
[n
->n_router_dns
++] = a
.in6
;
1102 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DNS server address, ignoring: %s", w
);
1109 int config_parse_radv_search_domains(
1111 const char *filename
,
1113 const char *section
,
1114 unsigned section_line
,
1122 const char *p
= rvalue
;
1130 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1132 r
= extract_first_word(&p
, &w
, NULL
, 0);
1136 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1142 r
= dns_name_apply_idna(w
, &idna
);
1144 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1148 r
= strv_push(&n
->router_search_domains
, idna
);
1152 r
= strv_push(&n
->router_search_domains
, w
);
1161 int config_parse_dhcp_server_ntp(
1163 const char *filename
,
1165 const char *section
,
1166 unsigned section_line
,
1174 const char *p
= rvalue
;
1182 _cleanup_free_
char *w
= NULL
;
1183 struct in_addr a
, *m
;
1185 r
= extract_first_word(&p
, &w
, NULL
, 0);
1189 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1195 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1196 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse NTP server address, ignoring: %s", w
);
1200 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1204 m
[n
->n_dhcp_server_ntp
++] = a
;
1205 n
->dhcp_server_ntp
= m
;
1209 int config_parse_dns(
1211 const char *filename
,
1213 const char *section
,
1214 unsigned section_line
,
1221 Network
*n
= userdata
;
1229 _cleanup_free_
char *w
= NULL
;
1230 union in_addr_union a
;
1231 struct in_addr_data
*m
;
1234 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1238 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Invalid syntax, ignoring: %s", rvalue
);
1244 r
= in_addr_from_string_auto(w
, &family
, &a
);
1246 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse dns server address, ignoring: %s", w
);
1250 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1254 m
[n
->n_dns
++] = (struct in_addr_data
) {
1265 int config_parse_dnssec_negative_trust_anchors(
1267 const char *filename
,
1269 const char *section
,
1270 unsigned section_line
,
1277 const char *p
= rvalue
;
1285 if (isempty(rvalue
)) {
1286 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1291 _cleanup_free_
char *w
= NULL
;
1293 r
= extract_first_word(&p
, &w
, NULL
, 0);
1295 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1301 r
= dns_name_is_valid(w
);
1303 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s is not a valid domain name, ignoring.", w
);
1307 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1311 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1321 int config_parse_ntp(
1323 const char *filename
,
1325 const char *section
,
1326 unsigned section_line
,
1340 if (isempty(rvalue
)) {
1346 _cleanup_free_
char *w
= NULL
;
1348 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1352 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract NTP server name, ignoring: %s", rvalue
);
1358 r
= dns_name_is_valid_or_address(w
);
1360 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s is not a valid domain name or IP address, ignoring.", w
);
1364 r
= strv_push(l
, w
);
1374 int config_parse_dhcp_user_class(
1376 const char *filename
,
1378 const char *section
,
1379 unsigned section_line
,
1393 if (isempty(rvalue
)) {
1399 _cleanup_free_
char *w
= NULL
;
1401 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1405 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to split user classes option, ignoring: %s", rvalue
);
1411 if (strlen(w
) > 255) {
1412 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s length is not in the range 1-255, ignoring.", w
);
1416 r
= strv_push(l
, w
);
1426 int config_parse_section_route_table(
1428 const char *filename
,
1430 const char *section
,
1431 unsigned section_line
,
1438 Network
*network
= data
;
1447 r
= safe_atou32(rvalue
, &rt
);
1449 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1450 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1454 if (streq_ptr(section
, "DHCP")) {
1455 network
->dhcp_route_table
= rt
;
1456 network
->dhcp_route_table_set
= true;
1457 } else { /* section is IPv6AcceptRA */
1458 network
->ipv6_accept_ra_route_table
= rt
;
1459 network
->ipv6_accept_ra_route_table_set
= true;
1465 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
, "Failed to parse DHCP use domains setting");
1467 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1468 [DHCP_USE_DOMAINS_NO
] = "no",
1469 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1470 [DHCP_USE_DOMAINS_YES
] = "yes",
1473 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1475 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1477 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1478 [LLDP_MODE_NO
] = "no",
1479 [LLDP_MODE_YES
] = "yes",
1480 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1483 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
1485 int config_parse_iaid(const char *unit
,
1486 const char *filename
,
1488 const char *section
,
1489 unsigned section_line
,
1495 Network
*network
= data
;
1504 r
= safe_atou32(rvalue
, &iaid
);
1506 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1507 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1511 network
->iaid
= iaid
;
1512 network
->iaid_set
= true;