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
= -1;
228 network
->hairpin
= -1;
229 network
->fast_leave
= -1;
230 network
->allow_port_to_be_root
= -1;
231 network
->unicast_flood
= -1;
232 network
->priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
;
234 network
->lldp_mode
= LLDP_MODE_ROUTERS_ONLY
;
236 network
->llmnr
= RESOLVE_SUPPORT_YES
;
237 network
->mdns
= RESOLVE_SUPPORT_NO
;
238 network
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
240 network
->link_local
= ADDRESS_FAMILY_IPV6
;
242 network
->ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
243 network
->ipv6_accept_ra
= -1;
244 network
->ipv6_dad_transmits
= -1;
245 network
->ipv6_hop_limit
= -1;
246 network
->ipv6_proxy_ndp
= -1;
247 network
->duid
.type
= _DUID_TYPE_INVALID
;
248 network
->proxy_arp
= -1;
250 network
->ipv6_accept_ra_use_dns
= true;
251 network
->ipv6_accept_ra_route_table
= RT_TABLE_MAIN
;
252 network
->ipv6_mtu
= 0;
254 dropin_dirname
= strjoina(network
->name
, ".network.d");
256 r
= config_parse_many(filename
, network_dirs
, dropin_dirname
,
262 "RoutingPolicyRule\0"
265 "DHCPv4\0" /* compat */
268 "IPv6NDPProxyAddress\0"
272 "IPv6PrefixDelegation\0"
274 config_item_perf_lookup
, network_network_gperf_lookup
,
275 CONFIG_PARSE_WARN
, network
);
279 network_apply_anonymize_if_set(network
);
281 /* IPMasquerade=yes implies IPForward=yes */
282 if (network
->ip_masquerade
)
283 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
285 LIST_PREPEND(networks
, manager
->networks
, network
);
287 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
291 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
295 LIST_FOREACH(routes
, route
, network
->static_routes
) {
296 if (!route
->family
) {
297 log_warning("Route section without Gateway field configured in %s. "
298 "Ignoring", filename
);
303 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
304 if (!address
->family
) {
305 log_warning("Address section without Address field configured in %s. "
306 "Ignoring", filename
);
316 int network_load(Manager
*manager
) {
318 _cleanup_strv_free_
char **files
= NULL
;
324 while ((network
= manager
->networks
))
325 network_free(network
);
327 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, network_dirs
);
329 return log_error_errno(r
, "Failed to enumerate network files: %m");
331 STRV_FOREACH_BACKWARDS(f
, files
) {
332 r
= network_load_one(manager
, *f
);
340 void network_free(Network
*network
) {
341 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
342 RoutingPolicyRule
*rule
;
354 free(network
->filename
);
356 free(network
->match_mac
);
357 strv_free(network
->match_path
);
358 strv_free(network
->match_driver
);
359 strv_free(network
->match_type
);
360 strv_free(network
->match_name
);
362 free(network
->description
);
363 free(network
->dhcp_vendor_class_identifier
);
364 strv_free(network
->dhcp_user_class
);
365 free(network
->dhcp_hostname
);
369 strv_free(network
->ntp
);
371 strv_free(network
->search_domains
);
372 strv_free(network
->route_domains
);
373 strv_free(network
->bind_carrier
);
375 netdev_unref(network
->bridge
);
376 netdev_unref(network
->bond
);
377 netdev_unref(network
->vrf
);
379 HASHMAP_FOREACH(netdev
, network
->stacked_netdevs
, i
) {
380 hashmap_remove(network
->stacked_netdevs
, netdev
->ifname
);
381 netdev_unref(netdev
);
383 hashmap_free(network
->stacked_netdevs
);
385 while ((route
= network
->static_routes
))
388 while ((address
= network
->static_addresses
))
389 address_free(address
);
391 while ((fdb_entry
= network
->static_fdb_entries
))
392 fdb_entry_free(fdb_entry
);
394 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
395 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
397 while ((label
= network
->address_labels
))
398 address_label_free(label
);
400 while ((prefix
= network
->static_prefixes
))
403 while ((rule
= network
->rules
))
404 routing_policy_rule_free(rule
);
406 hashmap_free(network
->addresses_by_section
);
407 hashmap_free(network
->routes_by_section
);
408 hashmap_free(network
->fdb_entries_by_section
);
409 hashmap_free(network
->address_labels_by_section
);
410 hashmap_free(network
->prefixes_by_section
);
411 hashmap_free(network
->rules_by_section
);
413 if (network
->manager
) {
414 if (network
->manager
->networks
)
415 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
417 if (network
->manager
->networks_by_name
)
418 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
423 condition_free_list(network
->match_host
);
424 condition_free_list(network
->match_virt
);
425 condition_free_list(network
->match_kernel_cmdline
);
426 condition_free_list(network
->match_kernel_version
);
427 condition_free_list(network
->match_arch
);
429 free(network
->dhcp_server_timezone
);
430 free(network
->dhcp_server_dns
);
431 free(network
->dhcp_server_ntp
);
433 set_free_free(network
->dnssec_negative_trust_anchors
);
438 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
445 network
= hashmap_get(manager
->networks_by_name
, name
);
454 int network_get(Manager
*manager
, struct udev_device
*device
,
455 const char *ifname
, const struct ether_addr
*address
,
458 struct udev_device
*parent
;
459 const char *path
= NULL
, *parent_driver
= NULL
, *driver
= NULL
, *devtype
= NULL
;
465 path
= udev_device_get_property_value(device
, "ID_PATH");
467 parent
= udev_device_get_parent(device
);
469 parent_driver
= udev_device_get_driver(parent
);
471 driver
= udev_device_get_property_value(device
, "ID_NET_DRIVER");
473 devtype
= udev_device_get_devtype(device
);
476 LIST_FOREACH(networks
, network
, manager
->networks
) {
477 if (net_match_config(network
->match_mac
, network
->match_path
,
478 network
->match_driver
, network
->match_type
,
479 network
->match_name
, network
->match_host
,
480 network
->match_virt
, network
->match_kernel_cmdline
,
481 network
->match_kernel_version
, network
->match_arch
,
482 address
, path
, parent_driver
, driver
,
484 if (network
->match_name
&& device
) {
486 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
488 attr
= udev_device_get_sysattr_value(device
, "name_assign_type");
490 (void) safe_atou8(attr
, &name_assign_type
);
492 if (name_assign_type
== NET_NAME_ENUM
)
493 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
494 ifname
, network
->filename
);
496 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
498 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
510 int network_apply(Network
*network
, Link
*link
) {
516 link
->network
= network
;
518 if (network
->ipv4ll_route
) {
521 r
= route_new_static(network
, NULL
, 0, &route
);
525 r
= inet_pton(AF_INET
, "169.254.0.0", &route
->dst
.in
);
531 route
->family
= AF_INET
;
532 route
->dst_prefixlen
= 16;
533 route
->scope
= RT_SCOPE_LINK
;
534 route
->priority
= IPV4LL_ROUTE_METRIC
;
535 route
->protocol
= RTPROT_STATIC
;
538 if (network
->n_dns
> 0 ||
539 !strv_isempty(network
->ntp
) ||
540 !strv_isempty(network
->search_domains
) ||
541 !strv_isempty(network
->route_domains
))
547 bool network_has_static_ipv6_addresses(Network
*network
) {
552 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
553 if (address
->family
== AF_INET6
)
560 int config_parse_netdev(const char *unit
,
561 const char *filename
,
564 unsigned section_line
,
570 Network
*network
= userdata
;
571 _cleanup_free_
char *kind_string
= NULL
;
582 kind_string
= strdup(lvalue
);
586 /* the keys are CamelCase versions of the kind */
587 for (p
= kind_string
; *p
; p
++)
590 kind
= netdev_kind_from_string(kind_string
);
591 if (kind
== _NETDEV_KIND_INVALID
) {
592 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Invalid NetDev kind: %s", lvalue
);
596 r
= netdev_get(network
->manager
, rvalue
, &netdev
);
598 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s could not be found, ignoring assignment: %s", lvalue
, rvalue
);
602 if (netdev
->kind
!= kind
) {
603 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "NetDev is not a %s, ignoring assignment: %s", lvalue
, rvalue
);
608 case NETDEV_KIND_BRIDGE
:
609 network
->bridge
= netdev
;
612 case NETDEV_KIND_BOND
:
613 network
->bond
= netdev
;
616 case NETDEV_KIND_VRF
:
617 network
->vrf
= netdev
;
620 case NETDEV_KIND_VLAN
:
621 case NETDEV_KIND_MACVLAN
:
622 case NETDEV_KIND_MACVTAP
:
623 case NETDEV_KIND_IPVLAN
:
624 case NETDEV_KIND_VXLAN
:
625 case NETDEV_KIND_VCAN
:
626 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
628 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Cannot add NetDev '%s' to network: %m", rvalue
);
634 assert_not_reached("Cannot parse NetDev");
642 int config_parse_domains(
644 const char *filename
,
647 unsigned section_line
,
662 if (isempty(rvalue
)) {
663 n
->search_domains
= strv_free(n
->search_domains
);
664 n
->route_domains
= strv_free(n
->route_domains
);
670 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
674 r
= extract_first_word(&p
, &w
, NULL
, 0);
676 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract search or route domain, ignoring: %s", rvalue
);
682 is_route
= w
[0] == '~';
683 domain
= is_route
? w
+ 1 : w
;
685 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
686 /* If the root domain appears as is, or the special token "*" is found, we'll consider this as
687 * routing domain, unconditionally. */
689 domain
= "."; /* make sure we don't allow empty strings, thus write the root domain as "." */
692 r
= dns_name_normalize(domain
, &normalized
);
694 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "'%s' is not a valid domain name, ignoring.", domain
);
700 if (is_localhost(domain
)) {
701 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "'localhost' domain names may not be configure as search or route domains, ignoring assignment: %s", domain
);
707 r
= strv_extend(&n
->route_domains
, domain
);
712 r
= strv_extend(&n
->search_domains
, domain
);
718 strv_uniq(n
->route_domains
);
719 strv_uniq(n
->search_domains
);
724 int config_parse_tunnel(const char *unit
,
725 const char *filename
,
728 unsigned section_line
,
734 Network
*network
= userdata
;
743 r
= netdev_get(network
->manager
, rvalue
, &netdev
);
745 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Tunnel is invalid, ignoring assignment: %s", rvalue
);
749 if (!IN_SET(netdev
->kind
,
755 NETDEV_KIND_IP6GRETAP
,
758 NETDEV_KIND_IP6TNL
)) {
759 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
760 "NetDev is not a tunnel, ignoring assignment: %s", rvalue
);
764 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
766 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Cannot add VLAN '%s' to network, ignoring: %m", rvalue
);
775 int config_parse_ipv4ll(
777 const char *filename
,
780 unsigned section_line
,
787 AddressFamilyBoolean
*link_local
= data
;
794 /* Note that this is mostly like
795 * config_parse_address_family_boolean(), except that it
796 * applies only to IPv4 */
798 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, parse_boolean(rvalue
));
803 int config_parse_dhcp(
805 const char *filename
,
808 unsigned section_line
,
815 AddressFamilyBoolean
*dhcp
= data
, s
;
822 /* Note that this is mostly like
823 * config_parse_address_family_boolean(), except that it
824 * understands some old names for the enum values */
826 s
= address_family_boolean_from_string(rvalue
);
829 /* Previously, we had a slightly different enum here,
830 * support its values for compatbility. */
832 if (streq(rvalue
, "none"))
833 s
= ADDRESS_FAMILY_NO
;
834 else if (streq(rvalue
, "v4"))
835 s
= ADDRESS_FAMILY_IPV4
;
836 else if (streq(rvalue
, "v6"))
837 s
= ADDRESS_FAMILY_IPV6
;
838 else if (streq(rvalue
, "both"))
839 s
= ADDRESS_FAMILY_YES
;
841 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DHCP option, ignoring: %s", rvalue
);
850 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
851 [DHCP_CLIENT_ID_MAC
] = "mac",
852 [DHCP_CLIENT_ID_DUID
] = "duid",
853 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
856 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
857 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
, "Failed to parse client identifier type");
859 int config_parse_ipv6token(
861 const char *filename
,
864 unsigned section_line
,
871 union in_addr_union buffer
;
872 struct in6_addr
*token
= data
;
880 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
882 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse IPv6 token, ignoring: %s", rvalue
);
886 r
= in_addr_is_null(AF_INET6
, &buffer
);
888 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
892 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
893 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
902 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
903 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
904 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
905 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
908 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
910 int config_parse_ipv6_privacy_extensions(
912 const char *filename
,
915 unsigned section_line
,
922 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
928 assert(ipv6_privacy_extensions
);
930 /* Our enum shall be a superset of booleans, hence first try
931 * to parse as boolean, and then as enum */
933 k
= parse_boolean(rvalue
);
935 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
937 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
939 IPv6PrivacyExtensions s
;
941 s
= ipv6_privacy_extensions_from_string(rvalue
);
944 if (streq(rvalue
, "kernel"))
945 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
947 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
952 *ipv6_privacy_extensions
= s
;
958 int config_parse_hostname(
960 const char *filename
,
963 unsigned section_line
,
970 char **hostname
= data
, *hn
= NULL
;
977 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
981 if (!hostname_is_valid(hn
, false)) {
982 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Hostname is not valid, ignoring assignment: %s", rvalue
);
988 *hostname
= hostname_cleanup(hn
);
992 int config_parse_timezone(
994 const char *filename
,
997 unsigned section_line
,
1004 char **datap
= data
, *tz
= NULL
;
1011 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1015 if (!timezone_is_valid(tz
)) {
1016 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Timezone is not valid, ignoring assignment: %s", rvalue
);
1027 int config_parse_dhcp_server_dns(
1029 const char *filename
,
1031 const char *section
,
1032 unsigned section_line
,
1040 const char *p
= rvalue
;
1048 _cleanup_free_
char *w
= NULL
;
1049 struct in_addr a
, *m
;
1051 r
= extract_first_word(&p
, &w
, NULL
, 0);
1055 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1061 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1062 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DNS server address, ignoring: %s", w
);
1066 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1070 m
[n
->n_dhcp_server_dns
++] = a
;
1071 n
->dhcp_server_dns
= m
;
1077 int config_parse_radv_dns(
1079 const char *filename
,
1081 const char *section
,
1082 unsigned section_line
,
1090 const char *p
= rvalue
;
1098 _cleanup_free_
char *w
= NULL
;
1099 union in_addr_union a
;
1101 r
= extract_first_word(&p
, &w
, NULL
, 0);
1105 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1111 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1114 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1118 m
[n
->n_router_dns
++] = a
.in6
;
1122 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DNS server address, ignoring: %s", w
);
1129 int config_parse_radv_search_domains(
1131 const char *filename
,
1133 const char *section
,
1134 unsigned section_line
,
1142 const char *p
= rvalue
;
1150 _cleanup_free_
char *w
= NULL
;
1151 _cleanup_free_
char *idna
= NULL
;
1153 r
= extract_first_word(&p
, &w
, NULL
, 0);
1157 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1163 r
= dns_name_apply_idna(w
, &idna
);
1165 r
= strv_push(&n
->router_search_domains
, idna
);
1168 } else if (r
== 0) {
1169 r
= strv_push(&n
->router_search_domains
, w
);
1178 int config_parse_dhcp_server_ntp(
1180 const char *filename
,
1182 const char *section
,
1183 unsigned section_line
,
1191 const char *p
= rvalue
;
1199 _cleanup_free_
char *w
= NULL
;
1200 struct in_addr a
, *m
;
1202 r
= extract_first_word(&p
, &w
, NULL
, 0);
1206 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1212 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1213 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse NTP server address, ignoring: %s", w
);
1217 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1221 m
[n
->n_dhcp_server_ntp
++] = a
;
1222 n
->dhcp_server_ntp
= m
;
1226 int config_parse_dns(
1228 const char *filename
,
1230 const char *section
,
1231 unsigned section_line
,
1238 Network
*n
= userdata
;
1246 _cleanup_free_
char *w
= NULL
;
1247 union in_addr_union a
;
1248 struct in_addr_data
*m
;
1251 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1255 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Invalid syntax, ignoring: %s", rvalue
);
1261 r
= in_addr_from_string_auto(w
, &family
, &a
);
1263 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse dns server address, ignoring: %s", w
);
1267 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1271 m
[n
->n_dns
++] = (struct in_addr_data
) {
1282 int config_parse_dnssec_negative_trust_anchors(
1284 const char *filename
,
1286 const char *section
,
1287 unsigned section_line
,
1294 const char *p
= rvalue
;
1302 if (isempty(rvalue
)) {
1303 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1308 _cleanup_free_
char *w
= NULL
;
1310 r
= extract_first_word(&p
, &w
, NULL
, 0);
1312 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1318 r
= dns_name_is_valid(w
);
1320 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s is not a valid domain name, ignoring.", w
);
1324 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1328 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1338 int config_parse_ntp(
1340 const char *filename
,
1342 const char *section
,
1343 unsigned section_line
,
1357 if (isempty(rvalue
)) {
1363 _cleanup_free_
char *w
= NULL
;
1365 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1369 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract NTP server name, ignoring: %s", rvalue
);
1375 r
= dns_name_is_valid_or_address(w
);
1377 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s is not a valid domain name or IP address, ignoring.", w
);
1381 r
= strv_push(l
, w
);
1391 int config_parse_dhcp_user_class(
1393 const char *filename
,
1395 const char *section
,
1396 unsigned section_line
,
1410 if (isempty(rvalue
)) {
1416 _cleanup_free_
char *w
= NULL
;
1418 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1422 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to split user classes option, ignoring: %s", rvalue
);
1428 if (strlen(w
) > 255) {
1429 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s length is not in the range 1-255, ignoring.", w
);
1433 r
= strv_push(l
, w
);
1443 int config_parse_dhcp_route_table(const char *unit
,
1444 const char *filename
,
1446 const char *section
,
1447 unsigned section_line
,
1453 Network
*network
= data
;
1462 r
= safe_atou32(rvalue
, &rt
);
1464 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1465 "Unable to read RouteTable, ignoring assignment: %s", rvalue
);
1469 network
->dhcp_route_table
= rt
;
1470 network
->dhcp_route_table_set
= true;
1475 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
, "Failed to parse DHCP use domains setting");
1477 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1478 [DHCP_USE_DOMAINS_NO
] = "no",
1479 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1480 [DHCP_USE_DOMAINS_YES
] = "yes",
1483 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1485 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1487 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1488 [LLDP_MODE_NO
] = "no",
1489 [LLDP_MODE_YES
] = "yes",
1490 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1493 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);