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
->multicast
= -1;
251 network
->allmulticast
= -1;
252 network
->ipv6_accept_ra_use_dns
= true;
253 network
->ipv6_accept_ra_route_table
= RT_TABLE_MAIN
;
254 network
->ipv6_mtu
= 0;
256 dropin_dirname
= strjoina(network
->name
, ".network.d");
258 r
= config_parse_many(filename
, network_dirs
, dropin_dirname
,
264 "RoutingPolicyRule\0"
267 "DHCPv4\0" /* compat */
270 "IPv6NDPProxyAddress\0"
274 "IPv6PrefixDelegation\0"
276 config_item_perf_lookup
, network_network_gperf_lookup
,
277 CONFIG_PARSE_WARN
, network
);
281 network_apply_anonymize_if_set(network
);
283 /* IPMasquerade=yes implies IPForward=yes */
284 if (network
->ip_masquerade
)
285 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
287 LIST_PREPEND(networks
, manager
->networks
, network
);
289 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
293 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
297 LIST_FOREACH(routes
, route
, network
->static_routes
) {
298 if (!route
->family
) {
299 log_warning("Route section without Gateway field configured in %s. "
300 "Ignoring", filename
);
305 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
306 if (!address
->family
) {
307 log_warning("Address section without Address field configured in %s. "
308 "Ignoring", filename
);
318 int network_load(Manager
*manager
) {
320 _cleanup_strv_free_
char **files
= NULL
;
326 while ((network
= manager
->networks
))
327 network_free(network
);
329 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, network_dirs
);
331 return log_error_errno(r
, "Failed to enumerate network files: %m");
333 STRV_FOREACH_BACKWARDS(f
, files
) {
334 r
= network_load_one(manager
, *f
);
342 void network_free(Network
*network
) {
343 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
344 RoutingPolicyRule
*rule
;
356 free(network
->filename
);
358 set_free_free(network
->match_mac
);
359 strv_free(network
->match_path
);
360 strv_free(network
->match_driver
);
361 strv_free(network
->match_type
);
362 strv_free(network
->match_name
);
364 free(network
->description
);
365 free(network
->dhcp_vendor_class_identifier
);
366 strv_free(network
->dhcp_user_class
);
367 free(network
->dhcp_hostname
);
371 strv_free(network
->ntp
);
373 strv_free(network
->search_domains
);
374 strv_free(network
->route_domains
);
375 strv_free(network
->bind_carrier
);
377 netdev_unref(network
->bridge
);
378 netdev_unref(network
->bond
);
379 netdev_unref(network
->vrf
);
381 HASHMAP_FOREACH(netdev
, network
->stacked_netdevs
, i
) {
382 hashmap_remove(network
->stacked_netdevs
, netdev
->ifname
);
383 netdev_unref(netdev
);
385 hashmap_free(network
->stacked_netdevs
);
387 while ((route
= network
->static_routes
))
390 while ((address
= network
->static_addresses
))
391 address_free(address
);
393 while ((fdb_entry
= network
->static_fdb_entries
))
394 fdb_entry_free(fdb_entry
);
396 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
397 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
399 while ((label
= network
->address_labels
))
400 address_label_free(label
);
402 while ((prefix
= network
->static_prefixes
))
405 while ((rule
= network
->rules
))
406 routing_policy_rule_free(rule
);
408 hashmap_free(network
->addresses_by_section
);
409 hashmap_free(network
->routes_by_section
);
410 hashmap_free(network
->fdb_entries_by_section
);
411 hashmap_free(network
->address_labels_by_section
);
412 hashmap_free(network
->prefixes_by_section
);
413 hashmap_free(network
->rules_by_section
);
415 if (network
->manager
) {
416 if (network
->manager
->networks
)
417 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
419 if (network
->manager
->networks_by_name
)
420 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
425 condition_free_list(network
->match_host
);
426 condition_free_list(network
->match_virt
);
427 condition_free_list(network
->match_kernel_cmdline
);
428 condition_free_list(network
->match_kernel_version
);
429 condition_free_list(network
->match_arch
);
431 free(network
->dhcp_server_timezone
);
432 free(network
->dhcp_server_dns
);
433 free(network
->dhcp_server_ntp
);
435 set_free_free(network
->dnssec_negative_trust_anchors
);
440 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
447 network
= hashmap_get(manager
->networks_by_name
, name
);
456 int network_get(Manager
*manager
, struct udev_device
*device
,
457 const char *ifname
, const struct ether_addr
*address
,
460 struct udev_device
*parent
;
461 const char *path
= NULL
, *parent_driver
= NULL
, *driver
= NULL
, *devtype
= NULL
;
467 path
= udev_device_get_property_value(device
, "ID_PATH");
469 parent
= udev_device_get_parent(device
);
471 parent_driver
= udev_device_get_driver(parent
);
473 driver
= udev_device_get_property_value(device
, "ID_NET_DRIVER");
475 devtype
= udev_device_get_devtype(device
);
478 LIST_FOREACH(networks
, network
, manager
->networks
) {
479 if (net_match_config(network
->match_mac
, network
->match_path
,
480 network
->match_driver
, network
->match_type
,
481 network
->match_name
, network
->match_host
,
482 network
->match_virt
, network
->match_kernel_cmdline
,
483 network
->match_kernel_version
, network
->match_arch
,
484 address
, path
, parent_driver
, driver
,
486 if (network
->match_name
&& device
) {
488 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
490 attr
= udev_device_get_sysattr_value(device
, "name_assign_type");
492 (void) safe_atou8(attr
, &name_assign_type
);
494 if (name_assign_type
== NET_NAME_ENUM
)
495 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
496 ifname
, network
->filename
);
498 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
500 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
512 int network_apply(Network
*network
, Link
*link
) {
518 link
->network
= network
;
520 if (network
->ipv4ll_route
) {
523 r
= route_new_static(network
, NULL
, 0, &route
);
527 r
= inet_pton(AF_INET
, "169.254.0.0", &route
->dst
.in
);
533 route
->family
= AF_INET
;
534 route
->dst_prefixlen
= 16;
535 route
->scope
= RT_SCOPE_LINK
;
536 route
->priority
= IPV4LL_ROUTE_METRIC
;
537 route
->protocol
= RTPROT_STATIC
;
540 if (network
->n_dns
> 0 ||
541 !strv_isempty(network
->ntp
) ||
542 !strv_isempty(network
->search_domains
) ||
543 !strv_isempty(network
->route_domains
))
549 bool network_has_static_ipv6_addresses(Network
*network
) {
554 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
555 if (address
->family
== AF_INET6
)
562 int config_parse_netdev(const char *unit
,
563 const char *filename
,
566 unsigned section_line
,
572 Network
*network
= userdata
;
573 _cleanup_free_
char *kind_string
= NULL
;
584 kind_string
= strdup(lvalue
);
588 /* the keys are CamelCase versions of the kind */
589 for (p
= kind_string
; *p
; p
++)
592 kind
= netdev_kind_from_string(kind_string
);
593 if (kind
== _NETDEV_KIND_INVALID
) {
594 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Invalid NetDev kind: %s", lvalue
);
598 r
= netdev_get(network
->manager
, rvalue
, &netdev
);
600 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s could not be found, ignoring assignment: %s", lvalue
, rvalue
);
604 if (netdev
->kind
!= kind
) {
605 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "NetDev is not a %s, ignoring assignment: %s", lvalue
, rvalue
);
610 case NETDEV_KIND_BRIDGE
:
611 network
->bridge
= netdev
;
614 case NETDEV_KIND_BOND
:
615 network
->bond
= netdev
;
618 case NETDEV_KIND_VRF
:
619 network
->vrf
= netdev
;
622 case NETDEV_KIND_VLAN
:
623 case NETDEV_KIND_MACVLAN
:
624 case NETDEV_KIND_MACVTAP
:
625 case NETDEV_KIND_IPVLAN
:
626 case NETDEV_KIND_VXLAN
:
627 case NETDEV_KIND_VCAN
:
628 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
630 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Cannot add NetDev '%s' to network: %m", rvalue
);
636 assert_not_reached("Cannot parse NetDev");
644 int config_parse_domains(
646 const char *filename
,
649 unsigned section_line
,
664 if (isempty(rvalue
)) {
665 n
->search_domains
= strv_free(n
->search_domains
);
666 n
->route_domains
= strv_free(n
->route_domains
);
672 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
676 r
= extract_first_word(&p
, &w
, NULL
, 0);
678 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract search or route domain, ignoring: %s", rvalue
);
684 is_route
= w
[0] == '~';
685 domain
= is_route
? w
+ 1 : w
;
687 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
688 /* If the root domain appears as is, or the special token "*" is found, we'll consider this as
689 * routing domain, unconditionally. */
691 domain
= "."; /* make sure we don't allow empty strings, thus write the root domain as "." */
694 r
= dns_name_normalize(domain
, &normalized
);
696 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "'%s' is not a valid domain name, ignoring.", domain
);
702 if (is_localhost(domain
)) {
703 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "'localhost' domain names may not be configure as search or route domains, ignoring assignment: %s", domain
);
709 r
= strv_extend(&n
->route_domains
, domain
);
714 r
= strv_extend(&n
->search_domains
, domain
);
720 strv_uniq(n
->route_domains
);
721 strv_uniq(n
->search_domains
);
726 int config_parse_tunnel(const char *unit
,
727 const char *filename
,
730 unsigned section_line
,
736 Network
*network
= userdata
;
745 r
= netdev_get(network
->manager
, rvalue
, &netdev
);
747 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Tunnel is invalid, ignoring assignment: %s", rvalue
);
751 if (!IN_SET(netdev
->kind
,
757 NETDEV_KIND_IP6GRETAP
,
760 NETDEV_KIND_IP6TNL
)) {
761 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
762 "NetDev is not a tunnel, ignoring assignment: %s", rvalue
);
766 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
768 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Cannot add VLAN '%s' to network, ignoring: %m", rvalue
);
777 int config_parse_ipv4ll(
779 const char *filename
,
782 unsigned section_line
,
789 AddressFamilyBoolean
*link_local
= data
;
796 /* Note that this is mostly like
797 * config_parse_address_family_boolean(), except that it
798 * applies only to IPv4 */
800 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, parse_boolean(rvalue
));
805 int config_parse_dhcp(
807 const char *filename
,
810 unsigned section_line
,
817 AddressFamilyBoolean
*dhcp
= data
, s
;
824 /* Note that this is mostly like
825 * config_parse_address_family_boolean(), except that it
826 * understands some old names for the enum values */
828 s
= address_family_boolean_from_string(rvalue
);
831 /* Previously, we had a slightly different enum here,
832 * support its values for compatbility. */
834 if (streq(rvalue
, "none"))
835 s
= ADDRESS_FAMILY_NO
;
836 else if (streq(rvalue
, "v4"))
837 s
= ADDRESS_FAMILY_IPV4
;
838 else if (streq(rvalue
, "v6"))
839 s
= ADDRESS_FAMILY_IPV6
;
840 else if (streq(rvalue
, "both"))
841 s
= ADDRESS_FAMILY_YES
;
843 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DHCP option, ignoring: %s", rvalue
);
852 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
853 [DHCP_CLIENT_ID_MAC
] = "mac",
854 [DHCP_CLIENT_ID_DUID
] = "duid",
855 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
858 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
859 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
, "Failed to parse client identifier type");
861 int config_parse_ipv6token(
863 const char *filename
,
866 unsigned section_line
,
873 union in_addr_union buffer
;
874 struct in6_addr
*token
= data
;
882 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
884 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse IPv6 token, ignoring: %s", rvalue
);
888 r
= in_addr_is_null(AF_INET6
, &buffer
);
890 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
894 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
895 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
904 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
905 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
906 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
907 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
910 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
912 int config_parse_ipv6_privacy_extensions(
914 const char *filename
,
917 unsigned section_line
,
924 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
930 assert(ipv6_privacy_extensions
);
932 /* Our enum shall be a superset of booleans, hence first try
933 * to parse as boolean, and then as enum */
935 k
= parse_boolean(rvalue
);
937 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
939 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
941 IPv6PrivacyExtensions s
;
943 s
= ipv6_privacy_extensions_from_string(rvalue
);
946 if (streq(rvalue
, "kernel"))
947 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
949 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
954 *ipv6_privacy_extensions
= s
;
960 int config_parse_hostname(
962 const char *filename
,
965 unsigned section_line
,
972 char **hostname
= data
, *hn
= NULL
;
979 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
983 if (!hostname_is_valid(hn
, false)) {
984 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Hostname is not valid, ignoring assignment: %s", rvalue
);
990 *hostname
= hostname_cleanup(hn
);
994 int config_parse_timezone(
996 const char *filename
,
999 unsigned section_line
,
1006 char **datap
= data
, *tz
= NULL
;
1013 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1017 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1018 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Timezone is not valid, ignoring assignment: %s", rvalue
);
1029 int config_parse_dhcp_server_dns(
1031 const char *filename
,
1033 const char *section
,
1034 unsigned section_line
,
1042 const char *p
= rvalue
;
1050 _cleanup_free_
char *w
= NULL
;
1051 struct in_addr a
, *m
;
1053 r
= extract_first_word(&p
, &w
, NULL
, 0);
1057 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1063 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1064 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DNS server address, ignoring: %s", w
);
1068 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1072 m
[n
->n_dhcp_server_dns
++] = a
;
1073 n
->dhcp_server_dns
= m
;
1079 int config_parse_radv_dns(
1081 const char *filename
,
1083 const char *section
,
1084 unsigned section_line
,
1092 const char *p
= rvalue
;
1100 _cleanup_free_
char *w
= NULL
;
1101 union in_addr_union a
;
1103 r
= extract_first_word(&p
, &w
, NULL
, 0);
1107 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1113 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1116 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1120 m
[n
->n_router_dns
++] = a
.in6
;
1124 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DNS server address, ignoring: %s", w
);
1131 int config_parse_radv_search_domains(
1133 const char *filename
,
1135 const char *section
,
1136 unsigned section_line
,
1144 const char *p
= rvalue
;
1152 _cleanup_free_
char *w
= NULL
;
1153 _cleanup_free_
char *idna
= NULL
;
1155 r
= extract_first_word(&p
, &w
, NULL
, 0);
1159 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1165 r
= dns_name_apply_idna(w
, &idna
);
1167 r
= strv_push(&n
->router_search_domains
, idna
);
1170 } else if (r
== 0) {
1171 r
= strv_push(&n
->router_search_domains
, w
);
1180 int config_parse_dhcp_server_ntp(
1182 const char *filename
,
1184 const char *section
,
1185 unsigned section_line
,
1193 const char *p
= rvalue
;
1201 _cleanup_free_
char *w
= NULL
;
1202 struct in_addr a
, *m
;
1204 r
= extract_first_word(&p
, &w
, NULL
, 0);
1208 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1214 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1215 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse NTP server address, ignoring: %s", w
);
1219 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1223 m
[n
->n_dhcp_server_ntp
++] = a
;
1224 n
->dhcp_server_ntp
= m
;
1228 int config_parse_dns(
1230 const char *filename
,
1232 const char *section
,
1233 unsigned section_line
,
1240 Network
*n
= userdata
;
1248 _cleanup_free_
char *w
= NULL
;
1249 union in_addr_union a
;
1250 struct in_addr_data
*m
;
1253 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1257 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Invalid syntax, ignoring: %s", rvalue
);
1263 r
= in_addr_from_string_auto(w
, &family
, &a
);
1265 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse dns server address, ignoring: %s", w
);
1269 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1273 m
[n
->n_dns
++] = (struct in_addr_data
) {
1284 int config_parse_dnssec_negative_trust_anchors(
1286 const char *filename
,
1288 const char *section
,
1289 unsigned section_line
,
1296 const char *p
= rvalue
;
1304 if (isempty(rvalue
)) {
1305 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1310 _cleanup_free_
char *w
= NULL
;
1312 r
= extract_first_word(&p
, &w
, NULL
, 0);
1314 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1320 r
= dns_name_is_valid(w
);
1322 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s is not a valid domain name, ignoring.", w
);
1326 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1330 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1340 int config_parse_ntp(
1342 const char *filename
,
1344 const char *section
,
1345 unsigned section_line
,
1359 if (isempty(rvalue
)) {
1365 _cleanup_free_
char *w
= NULL
;
1367 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1371 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract NTP server name, ignoring: %s", rvalue
);
1377 r
= dns_name_is_valid_or_address(w
);
1379 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s is not a valid domain name or IP address, ignoring.", w
);
1383 r
= strv_push(l
, w
);
1393 int config_parse_dhcp_user_class(
1395 const char *filename
,
1397 const char *section
,
1398 unsigned section_line
,
1412 if (isempty(rvalue
)) {
1418 _cleanup_free_
char *w
= NULL
;
1420 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1424 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to split user classes option, ignoring: %s", rvalue
);
1430 if (strlen(w
) > 255) {
1431 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s length is not in the range 1-255, ignoring.", w
);
1435 r
= strv_push(l
, w
);
1445 int config_parse_dhcp_route_table(const char *unit
,
1446 const char *filename
,
1448 const char *section
,
1449 unsigned section_line
,
1455 Network
*network
= data
;
1464 r
= safe_atou32(rvalue
, &rt
);
1466 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1467 "Unable to read RouteTable, ignoring assignment: %s", rvalue
);
1471 network
->dhcp_route_table
= rt
;
1472 network
->dhcp_route_table_set
= true;
1477 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
, "Failed to parse DHCP use domains setting");
1479 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1480 [DHCP_USE_DOMAINS_NO
] = "no",
1481 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1482 [DHCP_USE_DOMAINS_YES
] = "yes",
1485 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1487 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1489 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1490 [LLDP_MODE_NO
] = "no",
1491 [LLDP_MODE_YES
] = "yes",
1492 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1495 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);