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 "missing_network.h"
14 #include "network-internal.h"
15 #include "networkd-manager.h"
16 #include "networkd-network.h"
17 #include "parse-util.h"
19 #include "socket-util.h"
20 #include "stat-util.h"
21 #include "string-table.h"
22 #include "string-util.h"
26 /* Let's assume that anything above this number is a user misconfiguration. */
27 #define MAX_NTP_SERVERS 128
29 /* Set defaults following RFC7844 */
30 void network_apply_anonymize_if_set(Network
*network
) {
31 if (!network
->dhcp_anonymize
)
34 SHOULD NOT send the Host Name option */
35 network
->dhcp_send_hostname
= false;
36 /* RFC7844 section 3.:
37 MAY contain the Client Identifier option
39 clients MUST use client identifiers based solely
40 on the link-layer address */
41 /* NOTE: Using MAC, as it does not reveal extra information,
42 * and some servers might not answer if this option is not sent */
43 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
45 SHOULD NOT use the Vendor Class Identifier option */
46 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
47 /* RFC7844 section 3.6.:
48 The client intending to protect its privacy SHOULD only request a
49 minimal number of options in the PRL and SHOULD also randomly shuffle
50 the ordering of option codes in the PRL. If this random ordering
51 cannot be implemented, the client MAY order the option codes in the
52 PRL by option code number (lowest to highest).
54 /* NOTE: dhcp_use_mtu is false by default,
55 * though it was not initiallized to any value in network_load_one.
56 * Maybe there should be another var called *send*?
57 * (to use the MTU sent by the server but to do not send
58 * the option in the PRL). */
59 network
->dhcp_use_mtu
= false;
60 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
61 * but this is needed to use them. */
62 network
->dhcp_use_routes
= true;
63 /* RFC7844 section 3.6.
64 * same comments as previous option */
65 network
->dhcp_use_timezone
= false;
68 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
69 const char *kind_string
;
73 /* For test-networkd-conf, the check must be earlier than the assertions. */
78 assert(network
->manager
);
79 assert(network
->filename
);
82 if (kind
== _NETDEV_KIND_TUNNEL
)
83 kind_string
= "tunnel";
85 kind_string
= netdev_kind_to_string(kind
);
87 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
88 "%s: Invalid NetDev kind of %s, ignoring assignment.",
89 network
->filename
, name
);
92 r
= netdev_get(network
->manager
, name
, &netdev
);
94 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
95 network
->filename
, name
);
97 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
104 NETDEV_KIND_IP6GRETAP
,
107 NETDEV_KIND_IP6TNL
)))
108 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
109 "%s: NetDev %s is not a %s, ignoring assignment",
110 network
->filename
, name
, kind_string
);
112 *ret_netdev
= netdev_ref(netdev
);
116 static int network_resolve_stacked_netdevs(Network
*network
) {
123 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
124 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
126 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
130 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
134 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
136 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
137 network
->filename
, (const char *) name
);
145 static uint32_t network_get_stacked_netdevs_mtu(Network
*network
) {
150 HASHMAP_FOREACH(dev
, network
->stacked_netdevs
, i
)
151 if (dev
->kind
== NETDEV_KIND_VLAN
&& dev
->mtu
> 0)
152 /* See vlan_dev_change_mtu() in kernel.
153 * Note that the additional 4bytes may not be necessary for all devices. */
154 mtu
= MAX(mtu
, dev
->mtu
+ 4);
156 else if (dev
->kind
== NETDEV_KIND_MACVLAN
&& dev
->mtu
> mtu
)
157 /* See macvlan_change_mtu() in kernel. */
163 int network_verify(Network
*network
) {
164 Address
*address
, *address_next
;
165 Route
*route
, *route_next
;
166 FdbEntry
*fdb
, *fdb_next
;
167 Neighbor
*neighbor
, *neighbor_next
;
168 AddressLabel
*label
, *label_next
;
169 Prefix
*prefix
, *prefix_next
;
170 RoutingPolicyRule
*rule
, *rule_next
;
174 assert(network
->filename
);
176 /* skip out early if configuration does not match the environment */
177 if (!net_match_config(NULL
, NULL
, NULL
, NULL
, NULL
,
178 network
->match_host
, network
->match_virt
, network
->match_kernel_cmdline
,
179 network
->match_kernel_version
, network
->match_arch
,
180 NULL
, NULL
, NULL
, NULL
, NULL
))
181 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
182 "%s: Conditions in the file do not match the system environment, skipping.",
185 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
186 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
187 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
188 (void) network_resolve_stacked_netdevs(network
);
190 /* Free unnecessary entries. */
191 network
->bond_name
= mfree(network
->bond_name
);
192 network
->bridge_name
= mfree(network
->bridge_name
);
193 network
->vrf_name
= mfree(network
->vrf_name
);
194 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
197 /* Bonding slave does not support addressing. */
198 if (network
->ipv6_accept_ra
> 0) {
199 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
201 network
->ipv6_accept_ra
= 0;
203 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
204 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
206 network
->link_local
= ADDRESS_FAMILY_NO
;
208 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
209 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
211 network
->dhcp
= ADDRESS_FAMILY_NO
;
213 if (network
->dhcp_server
) {
214 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
216 network
->dhcp_server
= false;
218 if (network
->n_static_addresses
> 0) {
219 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
221 while ((address
= network
->static_addresses
))
222 address_free(address
);
224 if (network
->n_static_routes
> 0) {
225 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
227 while ((route
= network
->static_routes
))
232 if (network
->link_local
< 0)
233 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
235 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
236 network
->ipv6_accept_ra
= false;
238 /* IPMasquerade=yes implies IPForward=yes */
239 if (network
->ip_masquerade
)
240 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
242 network
->mtu_is_set
= network
->mtu
> 0;
243 mtu
= network_get_stacked_netdevs_mtu(network
);
244 if (network
->mtu
< mtu
) {
245 if (network
->mtu_is_set
)
246 log_notice("%s: Bumping MTUBytes= from %"PRIu32
" to %"PRIu32
" because of stacked device",
247 network
->filename
, network
->mtu
, mtu
);
251 if (network
->mtu_is_set
&& network
->dhcp_use_mtu
) {
252 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
253 "Disabling UseMTU=.", network
->filename
);
254 network
->dhcp_use_mtu
= false;
257 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
258 if (address_section_verify(address
) < 0)
259 address_free(address
);
261 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
262 if (route_section_verify(route
, network
) < 0)
265 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
266 if (section_is_invalid(fdb
->section
))
269 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
270 if (section_is_invalid(neighbor
->section
))
271 neighbor_free(neighbor
);
273 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
274 if (section_is_invalid(label
->section
))
275 address_label_free(label
);
277 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
278 if (section_is_invalid(prefix
->section
))
281 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
282 if (section_is_invalid(rule
->section
))
283 routing_policy_rule_free(rule
);
288 int network_load_one(Manager
*manager
, const char *filename
) {
289 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
290 _cleanup_(network_freep
) Network
*network
= NULL
;
291 _cleanup_fclose_
FILE *file
= NULL
;
292 const char *dropin_dirname
;
299 file
= fopen(filename
, "re");
307 if (null_or_empty_fd(fileno(file
))) {
308 log_debug("Skipping empty file: %s", filename
);
312 fname
= strdup(filename
);
316 name
= strdup(basename(filename
));
320 d
= strrchr(name
, '.');
326 dropin_dirname
= strjoina(name
, ".network.d");
328 network
= new(Network
, 1);
332 *network
= (Network
) {
333 .filename
= TAKE_PTR(fname
),
334 .name
= TAKE_PTR(name
),
336 .required_for_online
= true,
337 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
338 .dhcp
= ADDRESS_FAMILY_NO
,
339 .dhcp_use_ntp
= true,
340 .dhcp_use_dns
= true,
341 .dhcp_use_hostname
= true,
342 .dhcp_use_routes
= true,
343 /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
344 .dhcp_send_hostname
= true,
345 /* To enable/disable RFC7844 Anonymity Profiles */
346 .dhcp_anonymize
= false,
347 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
348 /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
349 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
350 .dhcp_route_table
= RT_TABLE_MAIN
,
351 .dhcp_route_table_set
= false,
352 /* NOTE: from man: UseMTU=... Defaults to false*/
353 .dhcp_use_mtu
= false,
354 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
355 .dhcp_use_timezone
= false,
356 .rapid_commit
= true,
358 .dhcp_server_emit_dns
= true,
359 .dhcp_server_emit_ntp
= true,
360 .dhcp_server_emit_router
= true,
361 .dhcp_server_emit_timezone
= true,
363 .router_emit_dns
= true,
364 .router_emit_domains
= true,
369 .allow_port_to_be_root
= -1,
371 .multicast_to_unicast
= -1,
372 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
374 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
376 .dns_default_route
= -1,
377 .llmnr
= RESOLVE_SUPPORT_YES
,
378 .mdns
= RESOLVE_SUPPORT_NO
,
379 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
380 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
382 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
383 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
385 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
386 .ipv6_accept_ra
= -1,
387 .ipv6_dad_transmits
= -1,
388 .ipv6_hop_limit
= -1,
389 .ipv6_proxy_ndp
= -1,
390 .duid
.type
= _DUID_TYPE_INVALID
,
395 .ipv6_accept_ra_use_dns
= true,
396 .ipv6_accept_ra_use_autonomous_prefix
= true,
397 .ipv6_accept_ra_use_onlink_prefix
= true,
398 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
399 .ipv6_accept_ra_route_table_set
= false,
401 .can_triple_sampling
= -1,
404 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
411 "RoutingPolicyRule\0"
414 "DHCPv4\0" /* compat */
417 "IPv6NDPProxyAddress\0"
421 "IPv6PrefixDelegation\0"
424 config_item_perf_lookup
, network_network_gperf_lookup
,
425 CONFIG_PARSE_WARN
, network
);
429 network_apply_anonymize_if_set(network
);
431 r
= network_add_ipv4ll_route(network
);
433 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
435 LIST_PREPEND(networks
, manager
->networks
, network
);
436 network
->manager
= manager
;
438 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
442 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
446 if (network_verify(network
) < 0)
453 int network_load(Manager
*manager
) {
455 _cleanup_strv_free_
char **files
= NULL
;
461 while ((network
= manager
->networks
))
462 network_free(network
);
464 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
466 return log_error_errno(r
, "Failed to enumerate network files: %m");
468 STRV_FOREACH_BACKWARDS(f
, files
) {
469 r
= network_load_one(manager
, *f
);
477 void network_free(Network
*network
) {
478 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
479 RoutingPolicyRule
*rule
;
490 free(network
->filename
);
492 set_free_free(network
->match_mac
);
493 strv_free(network
->match_path
);
494 strv_free(network
->match_driver
);
495 strv_free(network
->match_type
);
496 strv_free(network
->match_name
);
498 free(network
->description
);
499 free(network
->dhcp_vendor_class_identifier
);
500 strv_free(network
->dhcp_user_class
);
501 free(network
->dhcp_hostname
);
505 strv_free(network
->ntp
);
507 ordered_set_free_free(network
->search_domains
);
508 ordered_set_free_free(network
->route_domains
);
509 strv_free(network
->bind_carrier
);
511 ordered_set_free_free(network
->router_search_domains
);
512 free(network
->router_dns
);
514 free(network
->bridge_name
);
515 free(network
->bond_name
);
516 free(network
->vrf_name
);
517 hashmap_free_free_key(network
->stacked_netdev_names
);
518 netdev_unref(network
->bridge
);
519 netdev_unref(network
->bond
);
520 netdev_unref(network
->vrf
);
521 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
523 while ((route
= network
->static_routes
))
526 while ((address
= network
->static_addresses
))
527 address_free(address
);
529 while ((fdb_entry
= network
->static_fdb_entries
))
530 fdb_entry_free(fdb_entry
);
532 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
533 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
535 while ((neighbor
= network
->neighbors
))
536 neighbor_free(neighbor
);
538 while ((label
= network
->address_labels
))
539 address_label_free(label
);
541 while ((prefix
= network
->static_prefixes
))
544 while ((rule
= network
->rules
))
545 routing_policy_rule_free(rule
);
547 hashmap_free(network
->addresses_by_section
);
548 hashmap_free(network
->routes_by_section
);
549 hashmap_free(network
->fdb_entries_by_section
);
550 hashmap_free(network
->neighbors_by_section
);
551 hashmap_free(network
->address_labels_by_section
);
552 hashmap_free(network
->prefixes_by_section
);
553 hashmap_free(network
->rules_by_section
);
555 if (network
->manager
) {
556 if (network
->manager
->networks
)
557 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
559 if (network
->manager
->networks_by_name
&& network
->name
)
560 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
562 if (network
->manager
->duids_requesting_uuid
)
563 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
568 condition_free_list(network
->match_host
);
569 condition_free_list(network
->match_virt
);
570 condition_free_list(network
->match_kernel_cmdline
);
571 condition_free_list(network
->match_kernel_version
);
572 condition_free_list(network
->match_arch
);
574 free(network
->dhcp_server_timezone
);
575 free(network
->dhcp_server_dns
);
576 free(network
->dhcp_server_ntp
);
578 set_free_free(network
->dnssec_negative_trust_anchors
);
583 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
590 network
= hashmap_get(manager
->networks_by_name
, name
);
599 int network_get(Manager
*manager
, sd_device
*device
,
600 const char *ifname
, const struct ether_addr
*address
,
602 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
609 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
611 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
613 (void) sd_device_get_devtype(device
, &devtype
);
616 LIST_FOREACH(networks
, network
, manager
->networks
) {
617 if (net_match_config(network
->match_mac
, network
->match_path
,
618 network
->match_driver
, network
->match_type
,
619 network
->match_name
, network
->match_host
,
620 network
->match_virt
, network
->match_kernel_cmdline
,
621 network
->match_kernel_version
, network
->match_arch
,
622 address
, path
, driver
, devtype
, ifname
)) {
623 if (network
->match_name
&& device
) {
625 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
627 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
628 (void) safe_atou8(attr
, &name_assign_type
);
630 if (name_assign_type
== NET_NAME_ENUM
)
631 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
632 ifname
, network
->filename
);
634 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
636 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
648 int network_apply(Network
*network
, Link
*link
) {
652 link
->network
= network
;
654 if (network
->n_dns
> 0 ||
655 !strv_isempty(network
->ntp
) ||
656 !ordered_set_isempty(network
->search_domains
) ||
657 !ordered_set_isempty(network
->route_domains
))
663 bool network_has_static_ipv6_addresses(Network
*network
) {
668 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
669 if (address
->family
== AF_INET6
)
676 int config_parse_stacked_netdev(const char *unit
,
677 const char *filename
,
680 unsigned section_line
,
686 _cleanup_free_
char *name
= NULL
;
687 NetDevKind kind
= ltype
;
696 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
697 NETDEV_KIND_IPVLAN
, NETDEV_KIND_VXLAN
, _NETDEV_KIND_TUNNEL
));
699 if (!ifname_valid(rvalue
)) {
700 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
701 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
705 name
= strdup(rvalue
);
709 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
713 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
715 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
716 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
718 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
719 "NetDev '%s' specified twice, ignoring.", name
);
726 int config_parse_domains(
728 const char *filename
,
731 unsigned section_line
,
746 if (isempty(rvalue
)) {
747 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
748 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
754 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
758 r
= extract_first_word(&p
, &w
, NULL
, 0);
760 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
761 "Failed to extract search or route domain, ignoring: %s", rvalue
);
767 is_route
= w
[0] == '~';
768 domain
= is_route
? w
+ 1 : w
;
770 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
771 /* If the root domain appears as is, or the special token "*" is found, we'll
772 * consider this as routing domain, unconditionally. */
774 domain
= "."; /* make sure we don't allow empty strings, thus write the root
777 r
= dns_name_normalize(domain
, 0, &normalized
);
779 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
780 "'%s' is not a valid domain name, ignoring.", domain
);
786 if (is_localhost(domain
)) {
787 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
788 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
794 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
795 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
799 r
= ordered_set_put_strdup(*set
, domain
);
807 int config_parse_ipv4ll(
809 const char *filename
,
812 unsigned section_line
,
819 AddressFamilyBoolean
*link_local
= data
;
826 /* Note that this is mostly like
827 * config_parse_address_family_boolean(), except that it
828 * applies only to IPv4 */
830 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, parse_boolean(rvalue
));
835 int config_parse_dhcp(
837 const char *filename
,
840 unsigned section_line
,
847 AddressFamilyBoolean
*dhcp
= data
, s
;
854 /* Note that this is mostly like
855 * config_parse_address_family_boolean(), except that it
856 * understands some old names for the enum values */
858 s
= address_family_boolean_from_string(rvalue
);
861 /* Previously, we had a slightly different enum here,
862 * support its values for compatbility. */
864 if (streq(rvalue
, "none"))
865 s
= ADDRESS_FAMILY_NO
;
866 else if (streq(rvalue
, "v4"))
867 s
= ADDRESS_FAMILY_IPV4
;
868 else if (streq(rvalue
, "v6"))
869 s
= ADDRESS_FAMILY_IPV6
;
870 else if (streq(rvalue
, "both"))
871 s
= ADDRESS_FAMILY_YES
;
873 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
874 "Failed to parse DHCP option, ignoring: %s", rvalue
);
878 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
879 "DHCP=%s is deprecated, please use DHCP=%s instead.",
880 rvalue
, address_family_boolean_to_string(s
));
887 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
888 [DHCP_CLIENT_ID_MAC
] = "mac",
889 [DHCP_CLIENT_ID_DUID
] = "duid",
890 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
893 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
894 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
895 "Failed to parse client identifier type");
897 int config_parse_ipv6token(
899 const char *filename
,
902 unsigned section_line
,
909 union in_addr_union buffer
;
910 struct in6_addr
*token
= data
;
918 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
920 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
921 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
925 if (in_addr_is_null(AF_INET6
, &buffer
)) {
926 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
927 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
931 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
932 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
933 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
942 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
943 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
944 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
945 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
948 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
950 int config_parse_ipv6_privacy_extensions(
952 const char *filename
,
955 unsigned section_line
,
962 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
968 assert(ipv6_privacy_extensions
);
970 /* Our enum shall be a superset of booleans, hence first try
971 * to parse as boolean, and then as enum */
973 k
= parse_boolean(rvalue
);
975 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
977 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
979 IPv6PrivacyExtensions s
;
981 s
= ipv6_privacy_extensions_from_string(rvalue
);
984 if (streq(rvalue
, "kernel"))
985 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
987 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
988 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
993 *ipv6_privacy_extensions
= s
;
999 int config_parse_hostname(
1001 const char *filename
,
1003 const char *section
,
1004 unsigned section_line
,
1011 _cleanup_free_
char *hn
= NULL
;
1012 char **hostname
= data
;
1019 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1023 if (!hostname_is_valid(hn
, false)) {
1024 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1025 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1029 r
= dns_name_is_valid(hn
);
1031 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1032 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1036 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1037 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1041 return free_and_replace(*hostname
, hn
);
1044 int config_parse_timezone(
1046 const char *filename
,
1048 const char *section
,
1049 unsigned section_line
,
1056 _cleanup_free_
char *tz
= NULL
;
1057 char **datap
= data
;
1064 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1068 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1069 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1070 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1074 return free_and_replace(*datap
, tz
);
1077 int config_parse_dhcp_server_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 struct in_addr a
, *m
;
1101 r
= extract_first_word(&p
, &w
, NULL
, 0);
1105 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1106 "Failed to extract word, ignoring: %s", rvalue
);
1112 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1113 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1114 "Failed to parse DNS server address, ignoring: %s", w
);
1118 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1122 m
[n
->n_dhcp_server_dns
++] = a
;
1123 n
->dhcp_server_dns
= m
;
1129 int config_parse_radv_dns(
1131 const char *filename
,
1133 const char *section
,
1134 unsigned section_line
,
1142 const char *p
= rvalue
;
1150 _cleanup_free_
char *w
= NULL
;
1151 union in_addr_union a
;
1153 r
= extract_first_word(&p
, &w
, NULL
, 0);
1157 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1158 "Failed to extract word, ignoring: %s", rvalue
);
1164 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1167 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1171 m
[n
->n_router_dns
++] = a
.in6
;
1175 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1176 "Failed to parse DNS server address, ignoring: %s", w
);
1182 int config_parse_radv_search_domains(
1184 const char *filename
,
1186 const char *section
,
1187 unsigned section_line
,
1195 const char *p
= rvalue
;
1203 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1205 r
= extract_first_word(&p
, &w
, NULL
, 0);
1209 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1210 "Failed to extract word, ignoring: %s", rvalue
);
1216 r
= dns_name_apply_idna(w
, &idna
);
1218 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1219 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1222 /* transfer ownership to simplify subsequent operations */
1225 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1229 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1237 int config_parse_dhcp_server_ntp(
1239 const char *filename
,
1241 const char *section
,
1242 unsigned section_line
,
1250 const char *p
= rvalue
;
1258 _cleanup_free_
char *w
= NULL
;
1259 struct in_addr a
, *m
;
1261 r
= extract_first_word(&p
, &w
, NULL
, 0);
1265 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1266 "Failed to extract word, ignoring: %s", rvalue
);
1272 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1273 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1274 "Failed to parse NTP server address, ignoring: %s", w
);
1278 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1282 m
[n
->n_dhcp_server_ntp
++] = a
;
1283 n
->dhcp_server_ntp
= m
;
1287 int config_parse_dns(
1289 const char *filename
,
1291 const char *section
,
1292 unsigned section_line
,
1299 Network
*n
= userdata
;
1307 _cleanup_free_
char *w
= NULL
;
1308 union in_addr_union a
;
1309 struct in_addr_data
*m
;
1312 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1316 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1317 "Invalid syntax, ignoring: %s", rvalue
);
1323 r
= in_addr_from_string_auto(w
, &family
, &a
);
1325 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1326 "Failed to parse dns server address, ignoring: %s", w
);
1330 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1334 m
[n
->n_dns
++] = (struct in_addr_data
) {
1345 int config_parse_dnssec_negative_trust_anchors(
1347 const char *filename
,
1349 const char *section
,
1350 unsigned section_line
,
1357 const char *p
= rvalue
;
1365 if (isempty(rvalue
)) {
1366 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1371 _cleanup_free_
char *w
= NULL
;
1373 r
= extract_first_word(&p
, &w
, NULL
, 0);
1375 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1376 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1382 r
= dns_name_is_valid(w
);
1384 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1385 "%s is not a valid domain name, ignoring.", w
);
1389 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1393 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1403 int config_parse_ntp(
1405 const char *filename
,
1407 const char *section
,
1408 unsigned section_line
,
1422 if (isempty(rvalue
)) {
1428 _cleanup_free_
char *w
= NULL
;
1430 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1434 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1435 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1441 r
= dns_name_is_valid_or_address(w
);
1443 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1444 "%s is not a valid domain name or IP address, ignoring.", w
);
1448 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1449 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1450 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1451 MAX_NTP_SERVERS
, w
);
1455 r
= strv_consume(l
, TAKE_PTR(w
));
1463 int config_parse_dhcp_user_class(
1465 const char *filename
,
1467 const char *section
,
1468 unsigned section_line
,
1482 if (isempty(rvalue
)) {
1488 _cleanup_free_
char *w
= NULL
;
1490 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1494 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1495 "Failed to split user classes option, ignoring: %s", rvalue
);
1501 if (strlen(w
) > 255) {
1502 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1503 "%s length is not in the range 1-255, ignoring.", w
);
1507 r
= strv_push(l
, w
);
1517 int config_parse_section_route_table(
1519 const char *filename
,
1521 const char *section
,
1522 unsigned section_line
,
1529 Network
*network
= data
;
1538 r
= safe_atou32(rvalue
, &rt
);
1540 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1541 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1545 if (streq_ptr(section
, "DHCP")) {
1546 network
->dhcp_route_table
= rt
;
1547 network
->dhcp_route_table_set
= true;
1548 } else { /* section is IPv6AcceptRA */
1549 network
->ipv6_accept_ra_route_table
= rt
;
1550 network
->ipv6_accept_ra_route_table_set
= true;
1556 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1557 "Failed to parse DHCP use domains setting");
1559 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1560 [DHCP_USE_DOMAINS_NO
] = "no",
1561 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1562 [DHCP_USE_DOMAINS_YES
] = "yes",
1565 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1567 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1569 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1570 [LLDP_MODE_NO
] = "no",
1571 [LLDP_MODE_YES
] = "yes",
1572 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1575 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
1577 int config_parse_iaid(const char *unit
,
1578 const char *filename
,
1580 const char *section
,
1581 unsigned section_line
,
1587 Network
*network
= data
;
1596 r
= safe_atou32(rvalue
, &iaid
);
1598 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1599 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1603 network
->iaid
= iaid
;
1604 network
->iaid_set
= true;
1609 int config_parse_required_for_online(
1611 const char *filename
,
1613 const char *section
,
1614 unsigned section_line
,
1621 Network
*network
= data
;
1622 LinkOperationalState s
;
1623 bool required
= true;
1626 if (isempty(rvalue
)) {
1627 network
->required_for_online
= true;
1628 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1632 s
= link_operstate_from_string(rvalue
);
1634 r
= parse_boolean(rvalue
);
1636 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1637 "Failed to parse %s= setting, ignoring assignment: %s",
1643 s
= LINK_OPERSTATE_DEGRADED
;
1646 network
->required_for_online
= required
;
1647 network
->required_operstate_for_online
= s
;