1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2013 Tom Gundersen <teg@jklm.no>
11 #include "alloc-util.h"
12 #include "conf-files.h"
13 #include "conf-parser.h"
14 #include "dns-domain.h"
16 #include "hostname-util.h"
17 #include "in-addr-util.h"
18 #include "network-internal.h"
19 #include "networkd-manager.h"
20 #include "networkd-network.h"
21 #include "parse-util.h"
23 #include "stat-util.h"
24 #include "string-table.h"
25 #include "string-util.h"
29 static void network_config_hash_func(const void *p
, struct siphash
*state
) {
30 const NetworkConfigSection
*c
= p
;
32 siphash24_compress(c
->filename
, strlen(c
->filename
), state
);
33 siphash24_compress(&c
->line
, sizeof(c
->line
), state
);
36 static int network_config_compare_func(const void *a
, const void *b
) {
37 const NetworkConfigSection
*x
= a
, *y
= b
;
40 r
= strcmp(x
->filename
, y
->filename
);
44 return y
->line
- x
->line
;
47 const struct hash_ops network_config_hash_ops
= {
48 .hash
= network_config_hash_func
,
49 .compare
= network_config_compare_func
,
52 int network_config_section_new(const char *filename
, unsigned line
, NetworkConfigSection
**s
) {
53 NetworkConfigSection
*cs
;
55 cs
= malloc0(offsetof(NetworkConfigSection
, filename
) + strlen(filename
) + 1);
59 strcpy(cs
->filename
, filename
);
67 void network_config_section_free(NetworkConfigSection
*cs
) {
71 /* Set defaults following RFC7844 */
72 void network_apply_anonymize_if_set(Network
*network
) {
73 if (!network
->dhcp_anonymize
)
76 SHOULD NOT send the Host Name option */
77 network
->dhcp_send_hostname
= false;
78 /* RFC7844 section 3.:
79 MAY contain the Client Identifier option
81 clients MUST use client identifiers based solely
82 on the link-layer address */
83 /* NOTE: Using MAC, as it does not reveal extra information,
84 * and some servers might not answer if this option is not sent */
85 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
87 SHOULD NOT use the Vendor Class Identifier option */
88 /* NOTE: it was not initiallized to any value in network_load_one. */
89 network
->dhcp_vendor_class_identifier
= false;
90 /* RFC7844 section 3.6.:
91 The client intending to protect its privacy SHOULD only request a
92 minimal number of options in the PRL and SHOULD also randomly shuffle
93 the ordering of option codes in the PRL. If this random ordering
94 cannot be implemented, the client MAY order the option codes in the
95 PRL by option code number (lowest to highest).
97 /* NOTE: dhcp_use_mtu is false by default,
98 * though it was not initiallized to any value in network_load_one.
99 * Maybe there should be another var called *send*?
100 * (to use the MTU sent by the server but to do not send
101 * the option in the PRL). */
102 network
->dhcp_use_mtu
= false;
103 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
104 * but this is needed to use them. */
105 network
->dhcp_use_routes
= true;
106 /* RFC7844 section 3.6.
107 * same comments as previous option */
108 network
->dhcp_use_timezone
= false;
111 static int network_load_one(Manager
*manager
, const char *filename
) {
112 _cleanup_(network_freep
) Network
*network
= NULL
;
113 _cleanup_fclose_
FILE *file
= NULL
;
115 const char *dropin_dirname
;
123 file
= fopen(filename
, "re");
131 if (null_or_empty_fd(fileno(file
))) {
132 log_debug("Skipping empty file: %s", filename
);
136 network
= new0(Network
, 1);
140 network
->manager
= manager
;
142 LIST_HEAD_INIT(network
->static_addresses
);
143 LIST_HEAD_INIT(network
->static_routes
);
144 LIST_HEAD_INIT(network
->static_fdb_entries
);
145 LIST_HEAD_INIT(network
->ipv6_proxy_ndp_addresses
);
146 LIST_HEAD_INIT(network
->address_labels
);
147 LIST_HEAD_INIT(network
->static_prefixes
);
148 LIST_HEAD_INIT(network
->rules
);
150 network
->stacked_netdevs
= hashmap_new(&string_hash_ops
);
151 if (!network
->stacked_netdevs
)
154 network
->addresses_by_section
= hashmap_new(&network_config_hash_ops
);
155 if (!network
->addresses_by_section
)
158 network
->routes_by_section
= hashmap_new(&network_config_hash_ops
);
159 if (!network
->routes_by_section
)
162 network
->fdb_entries_by_section
= hashmap_new(NULL
);
163 if (!network
->fdb_entries_by_section
)
166 network
->address_labels_by_section
= hashmap_new(&network_config_hash_ops
);
167 if (!network
->address_labels_by_section
)
170 network
->prefixes_by_section
= hashmap_new(&network_config_hash_ops
);
171 if (!network
->prefixes_by_section
)
174 network
->rules_by_section
= hashmap_new(&network_config_hash_ops
);
175 if (!network
->rules_by_section
)
178 network
->filename
= strdup(filename
);
179 if (!network
->filename
)
182 network
->name
= strdup(basename(filename
));
186 d
= strrchr(network
->name
, '.');
190 assert(streq(d
, ".network"));
194 network
->required_for_online
= true;
195 network
->dhcp
= ADDRESS_FAMILY_NO
;
196 network
->dhcp_use_ntp
= true;
197 network
->dhcp_use_dns
= true;
198 network
->dhcp_use_hostname
= true;
199 network
->dhcp_use_routes
= true;
200 /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
201 network
->dhcp_send_hostname
= true;
202 /* To enable/disable RFC7844 Anonymity Profiles */
203 network
->dhcp_anonymize
= false;
204 network
->dhcp_route_metric
= DHCP_ROUTE_METRIC
;
205 /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
206 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
;
207 network
->dhcp_route_table
= RT_TABLE_MAIN
;
208 network
->dhcp_route_table_set
= false;
209 /* NOTE: the following vars were not set to any default,
210 * even if they are commented in the man?
211 * These vars might be overwriten by network_apply_anonymize_if_set */
212 network
->dhcp_vendor_class_identifier
= false;
213 /* NOTE: from man: UseMTU=... Defaults to false*/
214 network
->dhcp_use_mtu
= false;
215 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
216 network
->dhcp_use_timezone
= false;
217 network
->rapid_commit
= true;
219 network
->dhcp_server_emit_dns
= true;
220 network
->dhcp_server_emit_ntp
= true;
221 network
->dhcp_server_emit_router
= true;
222 network
->dhcp_server_emit_timezone
= true;
224 network
->router_emit_dns
= true;
225 network
->router_emit_domains
= true;
227 network
->use_bpdu
= true;
228 network
->allow_port_to_be_root
= true;
229 network
->unicast_flood
= true;
230 network
->priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
;
232 network
->lldp_mode
= LLDP_MODE_ROUTERS_ONLY
;
234 network
->llmnr
= RESOLVE_SUPPORT_YES
;
235 network
->mdns
= RESOLVE_SUPPORT_NO
;
236 network
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
238 network
->link_local
= ADDRESS_FAMILY_IPV6
;
240 network
->ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
241 network
->ipv6_accept_ra
= -1;
242 network
->ipv6_dad_transmits
= -1;
243 network
->ipv6_hop_limit
= -1;
244 network
->ipv6_proxy_ndp
= -1;
245 network
->duid
.type
= _DUID_TYPE_INVALID
;
246 network
->proxy_arp
= -1;
248 network
->ipv6_accept_ra_use_dns
= true;
249 network
->ipv6_accept_ra_route_table
= RT_TABLE_MAIN
;
250 network
->ipv6_mtu
= 0;
252 dropin_dirname
= strjoina(network
->name
, ".network.d");
254 r
= config_parse_many(filename
, network_dirs
, dropin_dirname
,
260 "RoutingPolicyRule\0"
263 "DHCPv4\0" /* compat */
266 "IPv6NDPProxyAddress\0"
270 "IPv6PrefixDelegation\0"
272 config_item_perf_lookup
, network_network_gperf_lookup
,
273 CONFIG_PARSE_WARN
, network
);
277 network_apply_anonymize_if_set(network
);
279 /* IPMasquerade=yes implies IPForward=yes */
280 if (network
->ip_masquerade
)
281 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
283 LIST_PREPEND(networks
, manager
->networks
, network
);
285 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
289 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
293 LIST_FOREACH(routes
, route
, network
->static_routes
) {
294 if (!route
->family
) {
295 log_warning("Route section without Gateway field configured in %s. "
296 "Ignoring", filename
);
301 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
302 if (!address
->family
) {
303 log_warning("Address section without Address field configured in %s. "
304 "Ignoring", filename
);
314 int network_load(Manager
*manager
) {
316 _cleanup_strv_free_
char **files
= NULL
;
322 while ((network
= manager
->networks
))
323 network_free(network
);
325 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, network_dirs
);
327 return log_error_errno(r
, "Failed to enumerate network files: %m");
329 STRV_FOREACH_BACKWARDS(f
, files
) {
330 r
= network_load_one(manager
, *f
);
338 void network_free(Network
*network
) {
339 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
340 RoutingPolicyRule
*rule
;
352 free(network
->filename
);
354 free(network
->match_mac
);
355 strv_free(network
->match_path
);
356 strv_free(network
->match_driver
);
357 strv_free(network
->match_type
);
358 strv_free(network
->match_name
);
360 free(network
->description
);
361 free(network
->dhcp_vendor_class_identifier
);
362 free(network
->dhcp_hostname
);
366 strv_free(network
->ntp
);
368 strv_free(network
->search_domains
);
369 strv_free(network
->route_domains
);
370 strv_free(network
->bind_carrier
);
372 netdev_unref(network
->bridge
);
373 netdev_unref(network
->bond
);
374 netdev_unref(network
->vrf
);
376 HASHMAP_FOREACH(netdev
, network
->stacked_netdevs
, i
) {
377 hashmap_remove(network
->stacked_netdevs
, netdev
->ifname
);
378 netdev_unref(netdev
);
380 hashmap_free(network
->stacked_netdevs
);
382 while ((route
= network
->static_routes
))
385 while ((address
= network
->static_addresses
))
386 address_free(address
);
388 while ((fdb_entry
= network
->static_fdb_entries
))
389 fdb_entry_free(fdb_entry
);
391 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
392 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
394 while ((label
= network
->address_labels
))
395 address_label_free(label
);
397 while ((prefix
= network
->static_prefixes
))
400 while ((rule
= network
->rules
))
401 routing_policy_rule_free(rule
);
403 hashmap_free(network
->addresses_by_section
);
404 hashmap_free(network
->routes_by_section
);
405 hashmap_free(network
->fdb_entries_by_section
);
406 hashmap_free(network
->address_labels_by_section
);
407 hashmap_free(network
->prefixes_by_section
);
408 hashmap_free(network
->rules_by_section
);
410 if (network
->manager
) {
411 if (network
->manager
->networks
)
412 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
414 if (network
->manager
->networks_by_name
)
415 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
420 condition_free_list(network
->match_host
);
421 condition_free_list(network
->match_virt
);
422 condition_free_list(network
->match_kernel_cmdline
);
423 condition_free_list(network
->match_kernel_version
);
424 condition_free_list(network
->match_arch
);
426 free(network
->dhcp_server_timezone
);
427 free(network
->dhcp_server_dns
);
428 free(network
->dhcp_server_ntp
);
430 set_free_free(network
->dnssec_negative_trust_anchors
);
435 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
442 network
= hashmap_get(manager
->networks_by_name
, name
);
451 int network_get(Manager
*manager
, struct udev_device
*device
,
452 const char *ifname
, const struct ether_addr
*address
,
455 struct udev_device
*parent
;
456 const char *path
= NULL
, *parent_driver
= NULL
, *driver
= NULL
, *devtype
= NULL
;
462 path
= udev_device_get_property_value(device
, "ID_PATH");
464 parent
= udev_device_get_parent(device
);
466 parent_driver
= udev_device_get_driver(parent
);
468 driver
= udev_device_get_property_value(device
, "ID_NET_DRIVER");
470 devtype
= udev_device_get_devtype(device
);
473 LIST_FOREACH(networks
, network
, manager
->networks
) {
474 if (net_match_config(network
->match_mac
, network
->match_path
,
475 network
->match_driver
, network
->match_type
,
476 network
->match_name
, network
->match_host
,
477 network
->match_virt
, network
->match_kernel_cmdline
,
478 network
->match_kernel_version
, network
->match_arch
,
479 address
, path
, parent_driver
, driver
,
481 if (network
->match_name
&& device
) {
483 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
485 attr
= udev_device_get_sysattr_value(device
, "name_assign_type");
487 (void) safe_atou8(attr
, &name_assign_type
);
489 if (name_assign_type
== NET_NAME_ENUM
)
490 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
491 ifname
, network
->filename
);
493 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
495 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
507 int network_apply(Network
*network
, Link
*link
) {
513 link
->network
= network
;
515 if (network
->ipv4ll_route
) {
518 r
= route_new_static(network
, NULL
, 0, &route
);
522 r
= inet_pton(AF_INET
, "169.254.0.0", &route
->dst
.in
);
528 route
->family
= AF_INET
;
529 route
->dst_prefixlen
= 16;
530 route
->scope
= RT_SCOPE_LINK
;
531 route
->priority
= IPV4LL_ROUTE_METRIC
;
532 route
->protocol
= RTPROT_STATIC
;
535 if (network
->n_dns
> 0 ||
536 !strv_isempty(network
->ntp
) ||
537 !strv_isempty(network
->search_domains
) ||
538 !strv_isempty(network
->route_domains
))
544 bool network_has_static_ipv6_addresses(Network
*network
) {
549 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
550 if (address
->family
== AF_INET6
)
557 int config_parse_netdev(const char *unit
,
558 const char *filename
,
561 unsigned section_line
,
567 Network
*network
= userdata
;
568 _cleanup_free_
char *kind_string
= NULL
;
579 kind_string
= strdup(lvalue
);
583 /* the keys are CamelCase versions of the kind */
584 for (p
= kind_string
; *p
; p
++)
587 kind
= netdev_kind_from_string(kind_string
);
588 if (kind
== _NETDEV_KIND_INVALID
) {
589 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Invalid NetDev kind: %s", lvalue
);
593 r
= netdev_get(network
->manager
, rvalue
, &netdev
);
595 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s could not be found, ignoring assignment: %s", lvalue
, rvalue
);
599 if (netdev
->kind
!= kind
) {
600 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "NetDev is not a %s, ignoring assignment: %s", lvalue
, rvalue
);
605 case NETDEV_KIND_BRIDGE
:
606 network
->bridge
= netdev
;
609 case NETDEV_KIND_BOND
:
610 network
->bond
= netdev
;
613 case NETDEV_KIND_VRF
:
614 network
->vrf
= netdev
;
617 case NETDEV_KIND_VLAN
:
618 case NETDEV_KIND_MACVLAN
:
619 case NETDEV_KIND_MACVTAP
:
620 case NETDEV_KIND_IPVLAN
:
621 case NETDEV_KIND_VXLAN
:
622 case NETDEV_KIND_VCAN
:
623 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
625 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Cannot add NetDev '%s' to network: %m", rvalue
);
631 assert_not_reached("Cannot parse NetDev");
639 int config_parse_domains(
641 const char *filename
,
644 unsigned section_line
,
659 if (isempty(rvalue
)) {
660 n
->search_domains
= strv_free(n
->search_domains
);
661 n
->route_domains
= strv_free(n
->route_domains
);
667 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
671 r
= extract_first_word(&p
, &w
, NULL
, 0);
673 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract search or route domain, ignoring: %s", rvalue
);
679 is_route
= w
[0] == '~';
680 domain
= is_route
? w
+ 1 : w
;
682 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
683 /* If the root domain appears as is, or the special token "*" is found, we'll consider this as
684 * routing domain, unconditionally. */
686 domain
= "."; /* make sure we don't allow empty strings, thus write the root domain as "." */
689 r
= dns_name_normalize(domain
, &normalized
);
691 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "'%s' is not a valid domain name, ignoring.", domain
);
697 if (is_localhost(domain
)) {
698 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "'localhost' domain names may not be configure as search or route domains, ignoring assignment: %s", domain
);
704 r
= strv_extend(&n
->route_domains
, domain
);
709 r
= strv_extend(&n
->search_domains
, domain
);
715 strv_uniq(n
->route_domains
);
716 strv_uniq(n
->search_domains
);
721 int config_parse_tunnel(const char *unit
,
722 const char *filename
,
725 unsigned section_line
,
731 Network
*network
= userdata
;
740 r
= netdev_get(network
->manager
, rvalue
, &netdev
);
742 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Tunnel is invalid, ignoring assignment: %s", rvalue
);
746 if (!IN_SET(netdev
->kind
,
752 NETDEV_KIND_IP6GRETAP
,
755 NETDEV_KIND_IP6TNL
)) {
756 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
757 "NetDev is not a tunnel, ignoring assignment: %s", rvalue
);
761 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
763 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Cannot add VLAN '%s' to network, ignoring: %m", rvalue
);
772 int config_parse_ipv4ll(
774 const char *filename
,
777 unsigned section_line
,
784 AddressFamilyBoolean
*link_local
= data
;
791 /* Note that this is mostly like
792 * config_parse_address_family_boolean(), except that it
793 * applies only to IPv4 */
795 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, parse_boolean(rvalue
));
800 int config_parse_dhcp(
802 const char *filename
,
805 unsigned section_line
,
812 AddressFamilyBoolean
*dhcp
= data
, s
;
819 /* Note that this is mostly like
820 * config_parse_address_family_boolean(), except that it
821 * understands some old names for the enum values */
823 s
= address_family_boolean_from_string(rvalue
);
826 /* Previously, we had a slightly different enum here,
827 * support its values for compatbility. */
829 if (streq(rvalue
, "none"))
830 s
= ADDRESS_FAMILY_NO
;
831 else if (streq(rvalue
, "v4"))
832 s
= ADDRESS_FAMILY_IPV4
;
833 else if (streq(rvalue
, "v6"))
834 s
= ADDRESS_FAMILY_IPV6
;
835 else if (streq(rvalue
, "both"))
836 s
= ADDRESS_FAMILY_YES
;
838 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DHCP option, ignoring: %s", rvalue
);
847 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
848 [DHCP_CLIENT_ID_MAC
] = "mac",
849 [DHCP_CLIENT_ID_DUID
] = "duid",
850 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
853 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
854 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
, "Failed to parse client identifier type");
856 int config_parse_ipv6token(
858 const char *filename
,
861 unsigned section_line
,
868 union in_addr_union buffer
;
869 struct in6_addr
*token
= data
;
877 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
879 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse IPv6 token, ignoring: %s", rvalue
);
883 r
= in_addr_is_null(AF_INET6
, &buffer
);
885 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
889 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
890 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
899 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
900 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
901 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
902 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
905 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
907 int config_parse_ipv6_privacy_extensions(
909 const char *filename
,
912 unsigned section_line
,
919 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
925 assert(ipv6_privacy_extensions
);
927 /* Our enum shall be a superset of booleans, hence first try
928 * to parse as boolean, and then as enum */
930 k
= parse_boolean(rvalue
);
932 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
934 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
936 IPv6PrivacyExtensions s
;
938 s
= ipv6_privacy_extensions_from_string(rvalue
);
941 if (streq(rvalue
, "kernel"))
942 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
944 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
949 *ipv6_privacy_extensions
= s
;
955 int config_parse_hostname(
957 const char *filename
,
960 unsigned section_line
,
967 char **hostname
= data
, *hn
= NULL
;
974 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
978 if (!hostname_is_valid(hn
, false)) {
979 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Hostname is not valid, ignoring assignment: %s", rvalue
);
985 *hostname
= hostname_cleanup(hn
);
989 int config_parse_timezone(
991 const char *filename
,
994 unsigned section_line
,
1001 char **datap
= data
, *tz
= NULL
;
1008 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1012 if (!timezone_is_valid(tz
)) {
1013 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Timezone is not valid, ignoring assignment: %s", rvalue
);
1024 int config_parse_dhcp_server_dns(
1026 const char *filename
,
1028 const char *section
,
1029 unsigned section_line
,
1037 const char *p
= rvalue
;
1045 _cleanup_free_
char *w
= NULL
;
1046 struct in_addr a
, *m
;
1048 r
= extract_first_word(&p
, &w
, NULL
, 0);
1052 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1058 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1059 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DNS server address, ignoring: %s", w
);
1063 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1067 m
[n
->n_dhcp_server_dns
++] = a
;
1068 n
->dhcp_server_dns
= m
;
1074 int config_parse_radv_dns(
1076 const char *filename
,
1078 const char *section
,
1079 unsigned section_line
,
1087 const char *p
= rvalue
;
1095 _cleanup_free_
char *w
= NULL
;
1096 union in_addr_union a
;
1098 r
= extract_first_word(&p
, &w
, NULL
, 0);
1102 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1108 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1111 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1115 m
[n
->n_router_dns
++] = a
.in6
;
1119 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DNS server address, ignoring: %s", w
);
1126 int config_parse_radv_search_domains(
1128 const char *filename
,
1130 const char *section
,
1131 unsigned section_line
,
1139 const char *p
= rvalue
;
1147 _cleanup_free_
char *w
= NULL
;
1148 _cleanup_free_
char *idna
= NULL
;
1150 r
= extract_first_word(&p
, &w
, NULL
, 0);
1154 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1160 r
= dns_name_apply_idna(w
, &idna
);
1162 r
= strv_push(&n
->router_search_domains
, idna
);
1165 } else if (r
== 0) {
1166 r
= strv_push(&n
->router_search_domains
, w
);
1175 int config_parse_dhcp_server_ntp(
1177 const char *filename
,
1179 const char *section
,
1180 unsigned section_line
,
1188 const char *p
= rvalue
;
1196 _cleanup_free_
char *w
= NULL
;
1197 struct in_addr a
, *m
;
1199 r
= extract_first_word(&p
, &w
, NULL
, 0);
1203 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1209 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1210 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse NTP server address, ignoring: %s", w
);
1214 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1218 m
[n
->n_dhcp_server_ntp
++] = a
;
1219 n
->dhcp_server_ntp
= m
;
1223 int config_parse_dns(
1225 const char *filename
,
1227 const char *section
,
1228 unsigned section_line
,
1235 Network
*n
= userdata
;
1243 _cleanup_free_
char *w
= NULL
;
1244 union in_addr_union a
;
1245 struct in_addr_data
*m
;
1248 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1252 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Invalid syntax, ignoring: %s", rvalue
);
1258 r
= in_addr_from_string_auto(w
, &family
, &a
);
1260 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse dns server address, ignoring: %s", w
);
1264 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1268 m
[n
->n_dns
++] = (struct in_addr_data
) {
1279 int config_parse_dnssec_negative_trust_anchors(
1281 const char *filename
,
1283 const char *section
,
1284 unsigned section_line
,
1291 const char *p
= rvalue
;
1299 if (isempty(rvalue
)) {
1300 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1305 _cleanup_free_
char *w
= NULL
;
1307 r
= extract_first_word(&p
, &w
, NULL
, 0);
1309 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1315 r
= dns_name_is_valid(w
);
1317 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s is not a valid domain name, ignoring.", w
);
1321 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1325 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1335 int config_parse_ntp(
1337 const char *filename
,
1339 const char *section
,
1340 unsigned section_line
,
1354 if (isempty(rvalue
)) {
1360 _cleanup_free_
char *w
= NULL
;
1362 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1366 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract NTP server name, ignoring: %s", rvalue
);
1372 r
= dns_name_is_valid_or_address(w
);
1374 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s is not a valid domain name or IP address, ignoring.", w
);
1378 r
= strv_push(l
, w
);
1388 int config_parse_dhcp_route_table(const char *unit
,
1389 const char *filename
,
1391 const char *section
,
1392 unsigned section_line
,
1398 Network
*network
= data
;
1407 r
= safe_atou32(rvalue
, &rt
);
1409 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1410 "Unable to read RouteTable, ignoring assignment: %s", rvalue
);
1414 network
->dhcp_route_table
= rt
;
1415 network
->dhcp_route_table_set
= true;
1420 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
, "Failed to parse DHCP use domains setting");
1422 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1423 [DHCP_USE_DOMAINS_NO
] = "no",
1424 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1425 [DHCP_USE_DOMAINS_YES
] = "yes",
1428 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1430 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1432 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1433 [LLDP_MODE_NO
] = "no",
1434 [LLDP_MODE_YES
] = "yes",
1435 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1438 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);