2 This file is part of systemd.
4 Copyright 2013 Tom Gundersen <teg@jklm.no>
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include "alloc-util.h"
24 #include "conf-files.h"
25 #include "conf-parser.h"
26 #include "dns-domain.h"
28 #include "hostname-util.h"
29 #include "in-addr-util.h"
30 #include "network-internal.h"
31 #include "networkd-manager.h"
32 #include "networkd-network.h"
33 #include "parse-util.h"
35 #include "stat-util.h"
36 #include "string-table.h"
37 #include "string-util.h"
41 static void network_config_hash_func(const void *p
, struct siphash
*state
) {
42 const NetworkConfigSection
*c
= p
;
44 siphash24_compress(c
->filename
, strlen(c
->filename
), state
);
45 siphash24_compress(&c
->line
, sizeof(c
->line
), state
);
48 static int network_config_compare_func(const void *a
, const void *b
) {
49 const NetworkConfigSection
*x
= a
, *y
= b
;
52 r
= strcmp(x
->filename
, y
->filename
);
56 return y
->line
- x
->line
;
59 const struct hash_ops network_config_hash_ops
= {
60 .hash
= network_config_hash_func
,
61 .compare
= network_config_compare_func
,
64 int network_config_section_new(const char *filename
, unsigned line
, NetworkConfigSection
**s
) {
65 NetworkConfigSection
*cs
;
67 cs
= malloc0(offsetof(NetworkConfigSection
, filename
) + strlen(filename
) + 1);
71 strcpy(cs
->filename
, filename
);
80 void network_config_section_free(NetworkConfigSection
*cs
) {
84 /* Set defaults following RFC7844 */
85 void network_apply_anonymize_if_set(Network
*network
) {
86 if (!network
->dhcp_anonymize
)
89 SHOULD NOT send the Host Name option */
90 network
->dhcp_send_hostname
= false;
91 /* RFC7844 section 3.:
92 MAY contain the Client Identifier option
94 clients MUST use client identifiers based solely
95 on the link-layer address */
96 /* NOTE: Using MAC, as it does not reveal extra information,
97 * and some servers might not answer if this option is not sent */
98 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
100 SHOULD NOT use the Vendor Class Identifier option */
101 /* NOTE: it was not initiallized to any value in network_load_one. */
102 network
->dhcp_vendor_class_identifier
= false;
103 /* RFC7844 section 3.6.:
104 The client intending to protect its privacy SHOULD only request a
105 minimal number of options in the PRL and SHOULD also randomly shuffle
106 the ordering of option codes in the PRL. If this random ordering
107 cannot be implemented, the client MAY order the option codes in the
108 PRL by option code number (lowest to highest).
110 /* NOTE: dhcp_use_mtu is false by default,
111 * though it was not initiallized to any value in network_load_one.
112 * Maybe there should be another var called *send*?
113 * (to use the MTU sent by the server but to do not send
114 * the option in the PRL). */
115 network
->dhcp_use_mtu
= false;
116 /* RFC7844 section 3.6.
117 * same comments as previous option */
118 network
->dhcp_use_routes
= false;
119 /* RFC7844 section 3.6.
120 * same comments as previous option */
121 network
->dhcp_use_timezone
= false;
124 static int network_load_one(Manager
*manager
, const char *filename
) {
125 _cleanup_network_free_ Network
*network
= NULL
;
126 _cleanup_fclose_
FILE *file
= NULL
;
128 const char *dropin_dirname
;
136 file
= fopen(filename
, "re");
144 if (null_or_empty_fd(fileno(file
))) {
145 log_debug("Skipping empty file: %s", filename
);
149 network
= new0(Network
, 1);
153 network
->manager
= manager
;
155 LIST_HEAD_INIT(network
->static_addresses
);
156 LIST_HEAD_INIT(network
->static_routes
);
157 LIST_HEAD_INIT(network
->static_fdb_entries
);
158 LIST_HEAD_INIT(network
->ipv6_proxy_ndp_addresses
);
159 LIST_HEAD_INIT(network
->address_labels
);
160 LIST_HEAD_INIT(network
->static_prefixes
);
161 LIST_HEAD_INIT(network
->rules
);
163 network
->stacked_netdevs
= hashmap_new(&string_hash_ops
);
164 if (!network
->stacked_netdevs
)
167 network
->addresses_by_section
= hashmap_new(&network_config_hash_ops
);
168 if (!network
->addresses_by_section
)
171 network
->routes_by_section
= hashmap_new(&network_config_hash_ops
);
172 if (!network
->routes_by_section
)
175 network
->fdb_entries_by_section
= hashmap_new(NULL
);
176 if (!network
->fdb_entries_by_section
)
179 network
->address_labels_by_section
= hashmap_new(&network_config_hash_ops
);
180 if (!network
->address_labels_by_section
)
183 network
->prefixes_by_section
= hashmap_new(&network_config_hash_ops
);
184 if (!network
->prefixes_by_section
)
187 network
->rules_by_section
= hashmap_new(&network_config_hash_ops
);
188 if (!network
->rules_by_section
)
191 network
->filename
= strdup(filename
);
192 if (!network
->filename
)
195 network
->name
= strdup(basename(filename
));
199 d
= strrchr(network
->name
, '.');
203 assert(streq(d
, ".network"));
207 network
->dhcp
= ADDRESS_FAMILY_NO
;
208 network
->dhcp_use_ntp
= true;
209 network
->dhcp_use_dns
= true;
210 network
->dhcp_use_hostname
= true;
211 /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
212 network
->dhcp_use_routes
= true;
213 /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
214 network
->dhcp_send_hostname
= true;
215 /* To enable/disable RFC7844 Anonymity Profiles */
216 network
->dhcp_anonymize
= false;
217 network
->dhcp_route_metric
= DHCP_ROUTE_METRIC
;
218 /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
219 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
;
220 network
->dhcp_route_table
= RT_TABLE_MAIN
;
221 network
->dhcp_route_table_set
= false;
222 /* NOTE: the following vars were not set to any default,
223 * even if they are commented in the man?
224 * These vars might be overwriten by network_apply_anonymize_if_set */
225 network
->dhcp_vendor_class_identifier
= false;
226 /* NOTE: from man: UseMTU=... Defaults to false*/
227 network
->dhcp_use_mtu
= false;
228 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
229 network
->dhcp_use_timezone
= false;
231 network
->dhcp_server_emit_dns
= true;
232 network
->dhcp_server_emit_ntp
= true;
233 network
->dhcp_server_emit_router
= true;
234 network
->dhcp_server_emit_timezone
= true;
236 network
->use_bpdu
= true;
237 network
->allow_port_to_be_root
= true;
238 network
->unicast_flood
= true;
239 network
->priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
;
241 network
->lldp_mode
= LLDP_MODE_ROUTERS_ONLY
;
243 network
->llmnr
= RESOLVE_SUPPORT_YES
;
244 network
->mdns
= RESOLVE_SUPPORT_NO
;
245 network
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
247 network
->link_local
= ADDRESS_FAMILY_IPV6
;
249 network
->ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
250 network
->ipv6_accept_ra
= -1;
251 network
->ipv6_dad_transmits
= -1;
252 network
->ipv6_hop_limit
= -1;
253 network
->ipv6_proxy_ndp
= -1;
254 network
->duid
.type
= _DUID_TYPE_INVALID
;
255 network
->proxy_arp
= -1;
257 network
->ipv6_accept_ra_use_dns
= true;
258 network
->ipv6_accept_ra_route_table
= RT_TABLE_MAIN
;
260 dropin_dirname
= strjoina(network
->name
, ".network.d");
262 r
= config_parse_many(filename
, network_dirs
, dropin_dirname
,
268 "RoutingPolicyRule\0"
271 "DHCPv4\0" /* compat */
274 "IPv6NDPProxyAddress\0"
278 "IPv6PrefixDelegation\0"
280 config_item_perf_lookup
, network_network_gperf_lookup
,
285 network_apply_anonymize_if_set(network
);
287 /* IPMasquerade=yes implies IPForward=yes */
288 if (network
->ip_masquerade
)
289 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
291 LIST_PREPEND(networks
, manager
->networks
, network
);
293 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
297 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
301 LIST_FOREACH(routes
, route
, network
->static_routes
) {
302 if (!route
->family
) {
303 log_warning("Route section without Gateway field configured in %s. "
304 "Ignoring", filename
);
309 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
310 if (!address
->family
) {
311 log_warning("Address section without Address field configured in %s. "
312 "Ignoring", filename
);
322 int network_load(Manager
*manager
) {
324 _cleanup_strv_free_
char **files
= NULL
;
330 while ((network
= manager
->networks
))
331 network_free(network
);
333 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, network_dirs
);
335 return log_error_errno(r
, "Failed to enumerate network files: %m");
337 STRV_FOREACH_BACKWARDS(f
, files
) {
338 r
= network_load_one(manager
, *f
);
346 void network_free(Network
*network
) {
347 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
348 RoutingPolicyRule
*rule
;
360 free(network
->filename
);
362 free(network
->match_mac
);
363 strv_free(network
->match_path
);
364 strv_free(network
->match_driver
);
365 strv_free(network
->match_type
);
366 strv_free(network
->match_name
);
368 free(network
->description
);
369 free(network
->dhcp_vendor_class_identifier
);
370 free(network
->dhcp_hostname
);
374 strv_free(network
->ntp
);
376 strv_free(network
->search_domains
);
377 strv_free(network
->route_domains
);
378 strv_free(network
->bind_carrier
);
380 netdev_unref(network
->bridge
);
381 netdev_unref(network
->bond
);
382 netdev_unref(network
->vrf
);
384 HASHMAP_FOREACH(netdev
, network
->stacked_netdevs
, i
) {
385 hashmap_remove(network
->stacked_netdevs
, netdev
->ifname
);
386 netdev_unref(netdev
);
388 hashmap_free(network
->stacked_netdevs
);
390 while ((route
= network
->static_routes
))
393 while ((address
= network
->static_addresses
))
394 address_free(address
);
396 while ((fdb_entry
= network
->static_fdb_entries
))
397 fdb_entry_free(fdb_entry
);
399 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
400 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
402 while ((label
= network
->address_labels
))
403 address_label_free(label
);
405 while ((prefix
= network
->static_prefixes
))
408 while ((rule
= network
->rules
))
409 routing_policy_rule_free(rule
);
411 hashmap_free(network
->addresses_by_section
);
412 hashmap_free(network
->routes_by_section
);
413 hashmap_free(network
->fdb_entries_by_section
);
414 hashmap_free(network
->address_labels_by_section
);
415 hashmap_free(network
->prefixes_by_section
);
416 hashmap_free(network
->rules_by_section
);
418 if (network
->manager
) {
419 if (network
->manager
->networks
)
420 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
422 if (network
->manager
->networks_by_name
)
423 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
428 condition_free_list(network
->match_host
);
429 condition_free_list(network
->match_virt
);
430 condition_free_list(network
->match_kernel
);
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
,
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
, "Can not add NetDev '%s' to network: %m", rvalue
);
638 assert_not_reached("Can not 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"
859 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
860 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
, "Failed to parse client identifier type");
862 int config_parse_ipv6token(
864 const char *filename
,
867 unsigned section_line
,
874 union in_addr_union buffer
;
875 struct in6_addr
*token
= data
;
883 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
885 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse IPv6 token, ignoring: %s", rvalue
);
889 r
= in_addr_is_null(AF_INET6
, &buffer
);
891 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "IPv6 token can not be the ANY address, ignoring: %s", rvalue
);
895 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
896 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "IPv6 token can not be longer than 64 bits, ignoring: %s", rvalue
);
905 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
906 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
907 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
908 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
911 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
913 int config_parse_ipv6_privacy_extensions(
915 const char *filename
,
918 unsigned section_line
,
925 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
931 assert(ipv6_privacy_extensions
);
933 /* Our enum shall be a superset of booleans, hence first try
934 * to parse as boolean, and then as enum */
936 k
= parse_boolean(rvalue
);
938 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
940 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
942 IPv6PrivacyExtensions s
;
944 s
= ipv6_privacy_extensions_from_string(rvalue
);
947 if (streq(rvalue
, "kernel"))
948 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
950 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
955 *ipv6_privacy_extensions
= s
;
961 int config_parse_hostname(
963 const char *filename
,
966 unsigned section_line
,
973 char **hostname
= data
, *hn
= NULL
;
980 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
984 if (!hostname_is_valid(hn
, false)) {
985 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Hostname is not valid, ignoring assignment: %s", rvalue
);
991 *hostname
= hostname_cleanup(hn
);
995 int config_parse_timezone(
997 const char *filename
,
1000 unsigned section_line
,
1007 char **datap
= data
, *tz
= NULL
;
1014 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1018 if (!timezone_is_valid(tz
)) {
1019 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Timezone is not valid, ignoring assignment: %s", rvalue
);
1030 int config_parse_dhcp_server_dns(
1032 const char *filename
,
1034 const char *section
,
1035 unsigned section_line
,
1043 const char *p
= rvalue
;
1051 _cleanup_free_
char *w
= NULL
;
1052 struct in_addr a
, *m
;
1054 r
= extract_first_word(&p
, &w
, NULL
, 0);
1058 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1064 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1065 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DNS server address, ignoring: %s", w
);
1069 m
= realloc(n
->dhcp_server_dns
, (n
->n_dhcp_server_dns
+ 1) * sizeof(struct in_addr
));
1073 m
[n
->n_dhcp_server_dns
++] = a
;
1074 n
->dhcp_server_dns
= m
;
1080 int config_parse_radv_dns(
1082 const char *filename
,
1084 const char *section
,
1085 unsigned section_line
,
1093 const char *p
= rvalue
;
1101 _cleanup_free_
char *w
= NULL
;
1102 union in_addr_union a
;
1104 r
= extract_first_word(&p
, &w
, NULL
, 0);
1108 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1114 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1117 m
= realloc(n
->router_dns
, (n
->n_router_dns
+ 1) * sizeof(struct in6_addr
));
1121 m
[n
->n_router_dns
++] = a
.in6
;
1125 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse DNS server address, ignoring: %s", w
);
1132 int config_parse_radv_search_domains(
1134 const char *filename
,
1136 const char *section
,
1137 unsigned section_line
,
1145 const char *p
= rvalue
;
1153 _cleanup_free_
char *w
= NULL
;
1154 _cleanup_free_
char *idna
= NULL
;
1156 r
= extract_first_word(&p
, &w
, NULL
, 0);
1160 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1166 r
= dns_name_apply_idna(w
, &idna
);
1168 r
= strv_push(&n
->router_search_domains
, idna
);
1171 } else if (r
== 0) {
1172 r
= strv_push(&n
->router_search_domains
, w
);
1181 int config_parse_dhcp_server_ntp(
1183 const char *filename
,
1185 const char *section
,
1186 unsigned section_line
,
1194 const char *p
= rvalue
;
1202 _cleanup_free_
char *w
= NULL
;
1203 struct in_addr a
, *m
;
1205 r
= extract_first_word(&p
, &w
, NULL
, 0);
1209 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract word, ignoring: %s", rvalue
);
1215 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1216 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse NTP server address, ignoring: %s", w
);
1220 m
= realloc(n
->dhcp_server_ntp
, (n
->n_dhcp_server_ntp
+ 1) * sizeof(struct in_addr
));
1224 m
[n
->n_dhcp_server_ntp
++] = a
;
1225 n
->dhcp_server_ntp
= m
;
1229 int config_parse_dns(
1231 const char *filename
,
1233 const char *section
,
1234 unsigned section_line
,
1241 Network
*n
= userdata
;
1249 _cleanup_free_
char *w
= NULL
;
1250 union in_addr_union a
;
1251 struct in_addr_data
*m
;
1254 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1258 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Invalid syntax, ignoring: %s", rvalue
);
1264 r
= in_addr_from_string_auto(w
, &family
, &a
);
1266 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse dns server address, ignoring: %s", w
);
1270 m
= realloc(n
->dns
, (n
->n_dns
+ 1) * sizeof(struct in_addr_data
));
1274 m
[n
->n_dns
++] = (struct in_addr_data
) {
1285 int config_parse_dnssec_negative_trust_anchors(
1287 const char *filename
,
1289 const char *section
,
1290 unsigned section_line
,
1297 const char *p
= rvalue
;
1305 if (isempty(rvalue
)) {
1306 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1311 _cleanup_free_
char *w
= NULL
;
1313 r
= extract_first_word(&p
, &w
, NULL
, 0);
1315 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1321 r
= dns_name_is_valid(w
);
1323 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s is not a valid domain name, ignoring.", w
);
1327 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1331 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1341 int config_parse_ntp(
1343 const char *filename
,
1345 const char *section
,
1346 unsigned section_line
,
1360 if (isempty(rvalue
)) {
1366 _cleanup_free_
char *w
= NULL
;
1368 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1372 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to extract NTP server name, ignoring: %s", rvalue
);
1378 r
= dns_name_is_valid_or_address(w
);
1380 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "%s is not a valid domain name or IP address, ignoring.", w
);
1384 r
= strv_push(l
, w
);
1394 int config_parse_dhcp_route_table(const char *unit
,
1395 const char *filename
,
1397 const char *section
,
1398 unsigned section_line
,
1404 Network
*network
= data
;
1413 r
= safe_atou32(rvalue
, &rt
);
1415 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1416 "Unable to read RouteTable, ignoring assignment: %s", rvalue
);
1420 network
->dhcp_route_table
= rt
;
1421 network
->dhcp_route_table_set
= true;
1426 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
, "Failed to parse DHCP use domains setting");
1428 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1429 [DHCP_USE_DOMAINS_NO
] = "no",
1430 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1431 [DHCP_USE_DOMAINS_YES
] = "yes",
1434 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1436 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1438 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1439 [LLDP_MODE_NO
] = "no",
1440 [LLDP_MODE_YES
] = "yes",
1441 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1444 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);