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 "network-internal.h"
14 #include "networkd-manager.h"
15 #include "networkd-network.h"
16 #include "parse-util.h"
18 #include "stat-util.h"
19 #include "string-table.h"
20 #include "string-util.h"
24 static void network_config_hash_func(const void *p
, struct siphash
*state
) {
25 const NetworkConfigSection
*c
= p
;
27 siphash24_compress(c
->filename
, strlen(c
->filename
), state
);
28 siphash24_compress(&c
->line
, sizeof(c
->line
), state
);
31 static int network_config_compare_func(const void *a
, const void *b
) {
32 const NetworkConfigSection
*x
= a
, *y
= b
;
35 r
= strcmp(x
->filename
, y
->filename
);
39 if (x
->line
< y
->line
)
41 if (x
->line
> y
->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
;
239 network
->dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
;
241 network
->link_local
= ADDRESS_FAMILY_IPV6
;
243 network
->ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
244 network
->ipv6_accept_ra
= -1;
245 network
->ipv6_dad_transmits
= -1;
246 network
->ipv6_hop_limit
= -1;
247 network
->ipv6_proxy_ndp
= -1;
248 network
->duid
.type
= _DUID_TYPE_INVALID
;
249 network
->proxy_arp
= -1;
251 network
->multicast
= -1;
252 network
->allmulticast
= -1;
253 network
->ipv6_accept_ra_use_dns
= true;
254 network
->ipv6_accept_ra_route_table
= RT_TABLE_MAIN
;
255 network
->ipv6_mtu
= 0;
257 dropin_dirname
= strjoina(network
->name
, ".network.d");
259 r
= config_parse_many(filename
, network_dirs
, dropin_dirname
,
265 "RoutingPolicyRule\0"
268 "DHCPv4\0" /* compat */
271 "IPv6NDPProxyAddress\0"
275 "IPv6PrefixDelegation\0"
278 config_item_perf_lookup
, network_network_gperf_lookup
,
279 CONFIG_PARSE_WARN
, network
);
283 network_apply_anonymize_if_set(network
);
285 /* IPMasquerade=yes implies IPForward=yes */
286 if (network
->ip_masquerade
)
287 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
289 LIST_PREPEND(networks
, manager
->networks
, network
);
291 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
295 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
299 LIST_FOREACH(routes
, route
, network
->static_routes
) {
300 if (!route
->family
) {
301 log_warning("Route section without Gateway field configured in %s. "
302 "Ignoring", filename
);
307 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
308 if (!address
->family
) {
309 log_warning("Address section without Address field configured in %s. "
310 "Ignoring", filename
);
320 int network_load(Manager
*manager
) {
322 _cleanup_strv_free_
char **files
= NULL
;
328 while ((network
= manager
->networks
))
329 network_free(network
);
331 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, network_dirs
);
333 return log_error_errno(r
, "Failed to enumerate network files: %m");
335 STRV_FOREACH_BACKWARDS(f
, files
) {
336 r
= network_load_one(manager
, *f
);
344 void network_free(Network
*network
) {
345 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
346 RoutingPolicyRule
*rule
;
358 free(network
->filename
);
360 set_free_free(network
->match_mac
);
361 strv_free(network
->match_path
);
362 strv_free(network
->match_driver
);
363 strv_free(network
->match_type
);
364 strv_free(network
->match_name
);
366 free(network
->description
);
367 free(network
->dhcp_vendor_class_identifier
);
368 strv_free(network
->dhcp_user_class
);
369 free(network
->dhcp_hostname
);
373 strv_free(network
->ntp
);
375 strv_free(network
->search_domains
);
376 strv_free(network
->route_domains
);
377 strv_free(network
->bind_carrier
);
379 netdev_unref(network
->bridge
);
380 netdev_unref(network
->bond
);
381 netdev_unref(network
->vrf
);
383 HASHMAP_FOREACH(netdev
, network
->stacked_netdevs
, i
) {
384 hashmap_remove(network
->stacked_netdevs
, netdev
->ifname
);
385 netdev_unref(netdev
);
387 hashmap_free(network
->stacked_netdevs
);
389 while ((route
= network
->static_routes
))
392 while ((address
= network
->static_addresses
))
393 address_free(address
);
395 while ((fdb_entry
= network
->static_fdb_entries
))
396 fdb_entry_free(fdb_entry
);
398 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
399 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
401 while ((label
= network
->address_labels
))
402 address_label_free(label
);
404 while ((prefix
= network
->static_prefixes
))
407 while ((rule
= network
->rules
))
408 routing_policy_rule_free(rule
);
410 hashmap_free(network
->addresses_by_section
);
411 hashmap_free(network
->routes_by_section
);
412 hashmap_free(network
->fdb_entries_by_section
);
413 hashmap_free(network
->address_labels_by_section
);
414 hashmap_free(network
->prefixes_by_section
);
415 hashmap_free(network
->rules_by_section
);
417 if (network
->manager
) {
418 if (network
->manager
->networks
)
419 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
421 if (network
->manager
->networks_by_name
)
422 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
427 condition_free_list(network
->match_host
);
428 condition_free_list(network
->match_virt
);
429 condition_free_list(network
->match_kernel_cmdline
);
430 condition_free_list(network
->match_kernel_version
);
431 condition_free_list(network
->match_arch
);
433 free(network
->dhcp_server_timezone
);
434 free(network
->dhcp_server_dns
);
435 free(network
->dhcp_server_ntp
);
437 set_free_free(network
->dnssec_negative_trust_anchors
);
442 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
449 network
= hashmap_get(manager
->networks_by_name
, name
);
458 int network_get(Manager
*manager
, struct udev_device
*device
,
459 const char *ifname
, const struct ether_addr
*address
,
462 struct udev_device
*parent
;
463 const char *path
= NULL
, *parent_driver
= NULL
, *driver
= NULL
, *devtype
= NULL
;
469 path
= udev_device_get_property_value(device
, "ID_PATH");
471 parent
= udev_device_get_parent(device
);
473 parent_driver
= udev_device_get_driver(parent
);
475 driver
= udev_device_get_property_value(device
, "ID_NET_DRIVER");
477 devtype
= udev_device_get_devtype(device
);
480 LIST_FOREACH(networks
, network
, manager
->networks
) {
481 if (net_match_config(network
->match_mac
, network
->match_path
,
482 network
->match_driver
, network
->match_type
,
483 network
->match_name
, network
->match_host
,
484 network
->match_virt
, network
->match_kernel_cmdline
,
485 network
->match_kernel_version
, network
->match_arch
,
486 address
, path
, parent_driver
, driver
,
488 if (network
->match_name
&& device
) {
490 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
492 attr
= udev_device_get_sysattr_value(device
, "name_assign_type");
494 (void) safe_atou8(attr
, &name_assign_type
);
496 if (name_assign_type
== NET_NAME_ENUM
)
497 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
498 ifname
, network
->filename
);
500 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
502 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
514 int network_apply(Network
*network
, Link
*link
) {
520 link
->network
= network
;
522 if (network
->ipv4ll_route
) {
525 r
= route_new_static(network
, NULL
, 0, &route
);
529 r
= inet_pton(AF_INET
, "169.254.0.0", &route
->dst
.in
);
535 route
->family
= AF_INET
;
536 route
->dst_prefixlen
= 16;
537 route
->scope
= RT_SCOPE_LINK
;
538 route
->priority
= IPV4LL_ROUTE_METRIC
;
539 route
->protocol
= RTPROT_STATIC
;
542 if (network
->n_dns
> 0 ||
543 !strv_isempty(network
->ntp
) ||
544 !strv_isempty(network
->search_domains
) ||
545 !strv_isempty(network
->route_domains
))
551 bool network_has_static_ipv6_addresses(Network
*network
) {
556 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
557 if (address
->family
== AF_INET6
)
564 int config_parse_netdev(const char *unit
,
565 const char *filename
,
568 unsigned section_line
,
574 Network
*network
= userdata
;
575 _cleanup_free_
char *kind_string
= NULL
;
586 kind_string
= strdup(lvalue
);
590 /* the keys are CamelCase versions of the kind */
591 for (p
= kind_string
; *p
; p
++)
594 kind
= netdev_kind_from_string(kind_string
);
595 if (kind
== _NETDEV_KIND_INVALID
) {
596 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Invalid NetDev kind: %s", lvalue
);
600 r
= netdev_get(network
->manager
, rvalue
, &netdev
);
602 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s could not be found, ignoring assignment: %s", lvalue
, rvalue
);
606 if (netdev
->kind
!= kind
) {
607 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "NetDev is not a %s, ignoring assignment: %s", lvalue
, rvalue
);
612 case NETDEV_KIND_BRIDGE
:
613 network
->bridge
= netdev
;
616 case NETDEV_KIND_BOND
:
617 network
->bond
= netdev
;
620 case NETDEV_KIND_VRF
:
621 network
->vrf
= netdev
;
624 case NETDEV_KIND_VLAN
:
625 case NETDEV_KIND_MACVLAN
:
626 case NETDEV_KIND_MACVTAP
:
627 case NETDEV_KIND_IPVLAN
:
628 case NETDEV_KIND_VXLAN
:
629 case NETDEV_KIND_VCAN
:
630 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
632 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Cannot add NetDev '%s' to network: %m", rvalue
);
638 assert_not_reached("Cannot parse NetDev");
646 int config_parse_domains(
648 const char *filename
,
651 unsigned section_line
,
666 if (isempty(rvalue
)) {
667 n
->search_domains
= strv_free(n
->search_domains
);
668 n
->route_domains
= strv_free(n
->route_domains
);
674 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
678 r
= extract_first_word(&p
, &w
, NULL
, 0);
680 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract search or route domain, ignoring: %s", rvalue
);
686 is_route
= w
[0] == '~';
687 domain
= is_route
? w
+ 1 : w
;
689 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
690 /* If the root domain appears as is, or the special token "*" is found, we'll consider this as
691 * routing domain, unconditionally. */
693 domain
= "."; /* make sure we don't allow empty strings, thus write the root domain as "." */
696 r
= dns_name_normalize(domain
, &normalized
);
698 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "'%s' is not a valid domain name, ignoring.", domain
);
704 if (is_localhost(domain
)) {
705 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "'localhost' domain names may not be configure as search or route domains, ignoring assignment: %s", domain
);
711 r
= strv_extend(&n
->route_domains
, domain
);
716 r
= strv_extend(&n
->search_domains
, domain
);
722 strv_uniq(n
->route_domains
);
723 strv_uniq(n
->search_domains
);
728 int config_parse_tunnel(const char *unit
,
729 const char *filename
,
732 unsigned section_line
,
738 Network
*network
= userdata
;
747 r
= netdev_get(network
->manager
, rvalue
, &netdev
);
749 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Tunnel is invalid, ignoring assignment: %s", rvalue
);
753 if (!IN_SET(netdev
->kind
,
759 NETDEV_KIND_IP6GRETAP
,
762 NETDEV_KIND_IP6TNL
)) {
763 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
764 "NetDev is not a tunnel, ignoring assignment: %s", rvalue
);
768 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
770 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Cannot add VLAN '%s' to network, ignoring: %m", rvalue
);
779 int config_parse_ipv4ll(
781 const char *filename
,
784 unsigned section_line
,
791 AddressFamilyBoolean
*link_local
= data
;
798 /* Note that this is mostly like
799 * config_parse_address_family_boolean(), except that it
800 * applies only to IPv4 */
802 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, parse_boolean(rvalue
));
807 int config_parse_dhcp(
809 const char *filename
,
812 unsigned section_line
,
819 AddressFamilyBoolean
*dhcp
= data
, s
;
826 /* Note that this is mostly like
827 * config_parse_address_family_boolean(), except that it
828 * understands some old names for the enum values */
830 s
= address_family_boolean_from_string(rvalue
);
833 /* Previously, we had a slightly different enum here,
834 * support its values for compatbility. */
836 if (streq(rvalue
, "none"))
837 s
= ADDRESS_FAMILY_NO
;
838 else if (streq(rvalue
, "v4"))
839 s
= ADDRESS_FAMILY_IPV4
;
840 else if (streq(rvalue
, "v6"))
841 s
= ADDRESS_FAMILY_IPV6
;
842 else if (streq(rvalue
, "both"))
843 s
= ADDRESS_FAMILY_YES
;
845 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DHCP option, ignoring: %s", rvalue
);
854 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
855 [DHCP_CLIENT_ID_MAC
] = "mac",
856 [DHCP_CLIENT_ID_DUID
] = "duid",
857 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
860 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
861 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
, "Failed to parse client identifier type");
863 int config_parse_ipv6token(
865 const char *filename
,
868 unsigned section_line
,
875 union in_addr_union buffer
;
876 struct in6_addr
*token
= data
;
884 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
886 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse IPv6 token, ignoring: %s", rvalue
);
890 r
= in_addr_is_null(AF_INET6
, &buffer
);
892 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
896 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
897 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
906 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
907 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
908 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
909 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
912 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
914 int config_parse_ipv6_privacy_extensions(
916 const char *filename
,
919 unsigned section_line
,
926 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
932 assert(ipv6_privacy_extensions
);
934 /* Our enum shall be a superset of booleans, hence first try
935 * to parse as boolean, and then as enum */
937 k
= parse_boolean(rvalue
);
939 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
941 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
943 IPv6PrivacyExtensions s
;
945 s
= ipv6_privacy_extensions_from_string(rvalue
);
948 if (streq(rvalue
, "kernel"))
949 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
951 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
956 *ipv6_privacy_extensions
= s
;
962 int config_parse_hostname(
964 const char *filename
,
967 unsigned section_line
,
974 char **hostname
= data
, *hn
= NULL
;
981 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
985 if (!hostname_is_valid(hn
, false)) {
986 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Hostname is not valid, ignoring assignment: %s", rvalue
);
992 *hostname
= hostname_cleanup(hn
);
996 int config_parse_timezone(
998 const char *filename
,
1000 const char *section
,
1001 unsigned section_line
,
1008 char **datap
= data
, *tz
= NULL
;
1015 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1019 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1020 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Timezone is not valid, ignoring assignment: %s", rvalue
);
1031 int config_parse_dhcp_server_dns(
1033 const char *filename
,
1035 const char *section
,
1036 unsigned section_line
,
1044 const char *p
= rvalue
;
1052 _cleanup_free_
char *w
= NULL
;
1053 struct in_addr a
, *m
;
1055 r
= extract_first_word(&p
, &w
, NULL
, 0);
1059 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1065 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1066 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DNS server address, ignoring: %s", w
);
1070 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1074 m
[n
->n_dhcp_server_dns
++] = a
;
1075 n
->dhcp_server_dns
= m
;
1081 int config_parse_radv_dns(
1083 const char *filename
,
1085 const char *section
,
1086 unsigned section_line
,
1094 const char *p
= rvalue
;
1102 _cleanup_free_
char *w
= NULL
;
1103 union in_addr_union a
;
1105 r
= extract_first_word(&p
, &w
, NULL
, 0);
1109 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1115 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1118 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1122 m
[n
->n_router_dns
++] = a
.in6
;
1126 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DNS server address, ignoring: %s", w
);
1133 int config_parse_radv_search_domains(
1135 const char *filename
,
1137 const char *section
,
1138 unsigned section_line
,
1146 const char *p
= rvalue
;
1154 _cleanup_free_
char *w
= NULL
;
1155 _cleanup_free_
char *idna
= NULL
;
1157 r
= extract_first_word(&p
, &w
, NULL
, 0);
1161 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1167 r
= dns_name_apply_idna(w
, &idna
);
1169 r
= strv_push(&n
->router_search_domains
, idna
);
1172 } else if (r
== 0) {
1173 r
= strv_push(&n
->router_search_domains
, w
);
1182 int config_parse_dhcp_server_ntp(
1184 const char *filename
,
1186 const char *section
,
1187 unsigned section_line
,
1195 const char *p
= rvalue
;
1203 _cleanup_free_
char *w
= NULL
;
1204 struct in_addr a
, *m
;
1206 r
= extract_first_word(&p
, &w
, NULL
, 0);
1210 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1216 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1217 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse NTP server address, ignoring: %s", w
);
1221 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1225 m
[n
->n_dhcp_server_ntp
++] = a
;
1226 n
->dhcp_server_ntp
= m
;
1230 int config_parse_dns(
1232 const char *filename
,
1234 const char *section
,
1235 unsigned section_line
,
1242 Network
*n
= userdata
;
1250 _cleanup_free_
char *w
= NULL
;
1251 union in_addr_union a
;
1252 struct in_addr_data
*m
;
1255 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1259 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Invalid syntax, ignoring: %s", rvalue
);
1265 r
= in_addr_from_string_auto(w
, &family
, &a
);
1267 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse dns server address, ignoring: %s", w
);
1271 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1275 m
[n
->n_dns
++] = (struct in_addr_data
) {
1286 int config_parse_dnssec_negative_trust_anchors(
1288 const char *filename
,
1290 const char *section
,
1291 unsigned section_line
,
1298 const char *p
= rvalue
;
1306 if (isempty(rvalue
)) {
1307 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1312 _cleanup_free_
char *w
= NULL
;
1314 r
= extract_first_word(&p
, &w
, NULL
, 0);
1316 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1322 r
= dns_name_is_valid(w
);
1324 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s is not a valid domain name, ignoring.", w
);
1328 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1332 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1342 int config_parse_ntp(
1344 const char *filename
,
1346 const char *section
,
1347 unsigned section_line
,
1361 if (isempty(rvalue
)) {
1367 _cleanup_free_
char *w
= NULL
;
1369 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1373 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract NTP server name, ignoring: %s", rvalue
);
1379 r
= dns_name_is_valid_or_address(w
);
1381 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s is not a valid domain name or IP address, ignoring.", w
);
1385 r
= strv_push(l
, w
);
1395 int config_parse_dhcp_user_class(
1397 const char *filename
,
1399 const char *section
,
1400 unsigned section_line
,
1414 if (isempty(rvalue
)) {
1420 _cleanup_free_
char *w
= NULL
;
1422 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1426 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to split user classes option, ignoring: %s", rvalue
);
1432 if (strlen(w
) > 255) {
1433 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s length is not in the range 1-255, ignoring.", w
);
1437 r
= strv_push(l
, w
);
1447 int config_parse_dhcp_route_table(const char *unit
,
1448 const char *filename
,
1450 const char *section
,
1451 unsigned section_line
,
1457 Network
*network
= data
;
1466 r
= safe_atou32(rvalue
, &rt
);
1468 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1469 "Unable to read RouteTable, ignoring assignment: %s", rvalue
);
1473 network
->dhcp_route_table
= rt
;
1474 network
->dhcp_route_table_set
= true;
1479 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
, "Failed to parse DHCP use domains setting");
1481 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1482 [DHCP_USE_DOMAINS_NO
] = "no",
1483 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1484 [DHCP_USE_DOMAINS_YES
] = "yes",
1487 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1489 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1491 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1492 [LLDP_MODE_NO
] = "no",
1493 [LLDP_MODE_YES
] = "yes",
1494 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1497 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);