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
;
74 assert(network
->manager
);
75 assert(network
->filename
);
81 if (kind
== _NETDEV_KIND_TUNNEL
)
82 kind_string
= "tunnel";
84 kind_string
= netdev_kind_to_string(kind
);
86 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
87 "%s: Invalid NetDev kind of %s, ignoring assignment.",
88 network
->filename
, name
);
91 r
= netdev_get(network
->manager
, name
, &netdev
);
93 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
94 network
->filename
, name
);
96 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
103 NETDEV_KIND_IP6GRETAP
,
106 NETDEV_KIND_IP6TNL
)))
107 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
108 "%s: NetDev %s is not a %s, ignoring assignment",
109 network
->filename
, name
, kind_string
);
111 *ret_netdev
= netdev_ref(netdev
);
115 static int network_resolve_stacked_netdevs(Network
*network
) {
122 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
123 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
125 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
129 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
133 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
135 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
136 network
->filename
, (const char *) name
);
144 static uint32_t network_get_stacked_netdevs_mtu(Network
*network
) {
149 HASHMAP_FOREACH(dev
, network
->stacked_netdevs
, i
)
150 if (dev
->kind
== NETDEV_KIND_VLAN
&& dev
->mtu
> 0)
151 /* See vlan_dev_change_mtu() in kernel.
152 * Note that the additional 4bytes may not be necessary for all devices. */
153 mtu
= MAX(mtu
, dev
->mtu
+ 4);
155 else if (dev
->kind
== NETDEV_KIND_MACVLAN
&& dev
->mtu
> mtu
)
156 /* See macvlan_change_mtu() in kernel. */
162 static int network_verify(Network
*network
) {
163 Address
*address
, *address_next
;
164 Route
*route
, *route_next
;
165 FdbEntry
*fdb
, *fdb_next
;
166 Neighbor
*neighbor
, *neighbor_next
;
167 AddressLabel
*label
, *label_next
;
168 Prefix
*prefix
, *prefix_next
;
169 RoutingPolicyRule
*rule
, *rule_next
;
173 assert(network
->filename
);
175 /* skip out early if configuration does not match the environment */
176 if (!net_match_config(NULL
, NULL
, NULL
, NULL
, NULL
,
177 network
->match_host
, network
->match_virt
, network
->match_kernel_cmdline
,
178 network
->match_kernel_version
, network
->match_arch
,
179 NULL
, NULL
, NULL
, NULL
, NULL
))
180 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
181 "%s: Conditions in the file do not match the system environment, skipping.",
184 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
185 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
186 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
187 (void) network_resolve_stacked_netdevs(network
);
189 /* Free unnecessary entries. */
190 network
->bond_name
= mfree(network
->bond_name
);
191 network
->bridge_name
= mfree(network
->bridge_name
);
192 network
->vrf_name
= mfree(network
->vrf_name
);
193 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
196 /* Bonding slave does not support addressing. */
197 if (network
->ipv6_accept_ra
> 0) {
198 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
200 network
->ipv6_accept_ra
= 0;
202 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
203 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
205 network
->link_local
= ADDRESS_FAMILY_NO
;
207 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
208 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
210 network
->dhcp
= ADDRESS_FAMILY_NO
;
212 if (network
->dhcp_server
) {
213 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
215 network
->dhcp_server
= false;
217 if (network
->n_static_addresses
> 0) {
218 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
220 while ((address
= network
->static_addresses
))
221 address_free(address
);
223 if (network
->n_static_routes
> 0) {
224 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
226 while ((route
= network
->static_routes
))
231 if (network
->link_local
< 0)
232 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
234 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
235 network
->ipv6_accept_ra
= false;
237 /* IPMasquerade=yes implies IPForward=yes */
238 if (network
->ip_masquerade
)
239 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
241 network
->mtu_is_set
= network
->mtu
> 0;
242 mtu
= network_get_stacked_netdevs_mtu(network
);
243 if (network
->mtu
< mtu
) {
244 if (network
->mtu_is_set
)
245 log_notice("%s: Bumping MTUBytes= from %"PRIu32
" to %"PRIu32
" because of stacked device",
246 network
->filename
, network
->mtu
, mtu
);
250 if (network
->mtu_is_set
&& network
->dhcp_use_mtu
) {
251 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
252 "Disabling UseMTU=.", network
->filename
);
253 network
->dhcp_use_mtu
= false;
256 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
257 if (address_section_verify(address
) < 0)
258 address_free(address
);
260 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
261 if (route_section_verify(route
, network
) < 0)
264 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
265 if (section_is_invalid(fdb
->section
))
268 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
269 if (section_is_invalid(neighbor
->section
))
270 neighbor_free(neighbor
);
272 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
273 if (section_is_invalid(label
->section
))
274 address_label_free(label
);
276 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
277 if (section_is_invalid(prefix
->section
))
280 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
281 if (section_is_invalid(rule
->section
))
282 routing_policy_rule_free(rule
);
287 int network_load_one(Manager
*manager
, const char *filename
) {
288 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
289 _cleanup_(network_freep
) Network
*network
= NULL
;
290 _cleanup_fclose_
FILE *file
= NULL
;
291 const char *dropin_dirname
;
298 file
= fopen(filename
, "re");
306 if (null_or_empty_fd(fileno(file
))) {
307 log_debug("Skipping empty file: %s", filename
);
311 fname
= strdup(filename
);
315 name
= strdup(basename(filename
));
319 d
= strrchr(name
, '.');
325 dropin_dirname
= strjoina(name
, ".network.d");
327 network
= new(Network
, 1);
331 *network
= (Network
) {
332 .filename
= TAKE_PTR(fname
),
333 .name
= TAKE_PTR(name
),
335 .required_for_online
= true,
336 .dhcp
= ADDRESS_FAMILY_NO
,
337 .dhcp_use_ntp
= true,
338 .dhcp_use_dns
= true,
339 .dhcp_use_hostname
= true,
340 .dhcp_use_routes
= true,
341 /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
342 .dhcp_send_hostname
= true,
343 /* To enable/disable RFC7844 Anonymity Profiles */
344 .dhcp_anonymize
= false,
345 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
346 /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
347 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
348 .dhcp_route_table
= RT_TABLE_MAIN
,
349 .dhcp_route_table_set
= false,
350 /* NOTE: from man: UseMTU=... Defaults to false*/
351 .dhcp_use_mtu
= false,
352 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
353 .dhcp_use_timezone
= false,
354 .rapid_commit
= true,
356 .dhcp_server_emit_dns
= true,
357 .dhcp_server_emit_ntp
= true,
358 .dhcp_server_emit_router
= true,
359 .dhcp_server_emit_timezone
= true,
361 .router_emit_dns
= true,
362 .router_emit_domains
= true,
367 .allow_port_to_be_root
= -1,
369 .multicast_to_unicast
= -1,
370 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
372 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
374 .dns_default_route
= -1,
375 .llmnr
= RESOLVE_SUPPORT_YES
,
376 .mdns
= RESOLVE_SUPPORT_NO
,
377 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
378 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
380 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
381 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
383 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
384 .ipv6_accept_ra
= -1,
385 .ipv6_dad_transmits
= -1,
386 .ipv6_hop_limit
= -1,
387 .ipv6_proxy_ndp
= -1,
388 .duid
.type
= _DUID_TYPE_INVALID
,
393 .ipv6_accept_ra_use_dns
= true,
394 .ipv6_accept_ra_use_autonomous_prefix
= true,
395 .ipv6_accept_ra_use_onlink_prefix
= true,
396 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
397 .ipv6_accept_ra_route_table_set
= false,
399 .can_triple_sampling
= -1,
402 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
409 "RoutingPolicyRule\0"
412 "DHCPv4\0" /* compat */
415 "IPv6NDPProxyAddress\0"
419 "IPv6PrefixDelegation\0"
422 config_item_perf_lookup
, network_network_gperf_lookup
,
423 CONFIG_PARSE_WARN
, network
);
427 network_apply_anonymize_if_set(network
);
429 r
= network_add_ipv4ll_route(network
);
431 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
433 LIST_PREPEND(networks
, manager
->networks
, network
);
434 network
->manager
= manager
;
436 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
440 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
444 if (network_verify(network
) < 0)
451 int network_load(Manager
*manager
) {
453 _cleanup_strv_free_
char **files
= NULL
;
459 while ((network
= manager
->networks
))
460 network_free(network
);
462 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
464 return log_error_errno(r
, "Failed to enumerate network files: %m");
466 STRV_FOREACH_BACKWARDS(f
, files
) {
467 r
= network_load_one(manager
, *f
);
475 void network_free(Network
*network
) {
476 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
477 RoutingPolicyRule
*rule
;
488 free(network
->filename
);
490 set_free_free(network
->match_mac
);
491 strv_free(network
->match_path
);
492 strv_free(network
->match_driver
);
493 strv_free(network
->match_type
);
494 strv_free(network
->match_name
);
496 free(network
->description
);
497 free(network
->dhcp_vendor_class_identifier
);
498 strv_free(network
->dhcp_user_class
);
499 free(network
->dhcp_hostname
);
503 strv_free(network
->ntp
);
505 ordered_set_free_free(network
->search_domains
);
506 ordered_set_free_free(network
->route_domains
);
507 strv_free(network
->bind_carrier
);
509 ordered_set_free_free(network
->router_search_domains
);
510 free(network
->router_dns
);
512 free(network
->bridge_name
);
513 free(network
->bond_name
);
514 free(network
->vrf_name
);
515 hashmap_free_free_key(network
->stacked_netdev_names
);
516 netdev_unref(network
->bridge
);
517 netdev_unref(network
->bond
);
518 netdev_unref(network
->vrf
);
519 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
521 while ((route
= network
->static_routes
))
524 while ((address
= network
->static_addresses
))
525 address_free(address
);
527 while ((fdb_entry
= network
->static_fdb_entries
))
528 fdb_entry_free(fdb_entry
);
530 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
531 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
533 while ((neighbor
= network
->neighbors
))
534 neighbor_free(neighbor
);
536 while ((label
= network
->address_labels
))
537 address_label_free(label
);
539 while ((prefix
= network
->static_prefixes
))
542 while ((rule
= network
->rules
))
543 routing_policy_rule_free(rule
);
545 hashmap_free(network
->addresses_by_section
);
546 hashmap_free(network
->routes_by_section
);
547 hashmap_free(network
->fdb_entries_by_section
);
548 hashmap_free(network
->neighbors_by_section
);
549 hashmap_free(network
->address_labels_by_section
);
550 hashmap_free(network
->prefixes_by_section
);
551 hashmap_free(network
->rules_by_section
);
553 if (network
->manager
) {
554 if (network
->manager
->networks
)
555 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
557 if (network
->manager
->networks_by_name
&& network
->name
)
558 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
560 if (network
->manager
->duids_requesting_uuid
)
561 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
566 condition_free_list(network
->match_host
);
567 condition_free_list(network
->match_virt
);
568 condition_free_list(network
->match_kernel_cmdline
);
569 condition_free_list(network
->match_kernel_version
);
570 condition_free_list(network
->match_arch
);
572 free(network
->dhcp_server_timezone
);
573 free(network
->dhcp_server_dns
);
574 free(network
->dhcp_server_ntp
);
576 set_free_free(network
->dnssec_negative_trust_anchors
);
581 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
588 network
= hashmap_get(manager
->networks_by_name
, name
);
597 int network_get(Manager
*manager
, sd_device
*device
,
598 const char *ifname
, const struct ether_addr
*address
,
600 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
607 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
609 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
611 (void) sd_device_get_devtype(device
, &devtype
);
614 LIST_FOREACH(networks
, network
, manager
->networks
) {
615 if (net_match_config(network
->match_mac
, network
->match_path
,
616 network
->match_driver
, network
->match_type
,
617 network
->match_name
, network
->match_host
,
618 network
->match_virt
, network
->match_kernel_cmdline
,
619 network
->match_kernel_version
, network
->match_arch
,
620 address
, path
, driver
, devtype
, ifname
)) {
621 if (network
->match_name
&& device
) {
623 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
625 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
626 (void) safe_atou8(attr
, &name_assign_type
);
628 if (name_assign_type
== NET_NAME_ENUM
)
629 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
630 ifname
, network
->filename
);
632 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
634 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
646 int network_apply(Network
*network
, Link
*link
) {
650 link
->network
= network
;
652 if (network
->n_dns
> 0 ||
653 !strv_isempty(network
->ntp
) ||
654 !ordered_set_isempty(network
->search_domains
) ||
655 !ordered_set_isempty(network
->route_domains
))
661 bool network_has_static_ipv6_addresses(Network
*network
) {
666 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
667 if (address
->family
== AF_INET6
)
674 int config_parse_stacked_netdev(const char *unit
,
675 const char *filename
,
678 unsigned section_line
,
684 _cleanup_free_
char *name
= NULL
;
685 NetDevKind kind
= ltype
;
694 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
695 NETDEV_KIND_IPVLAN
, NETDEV_KIND_VXLAN
, _NETDEV_KIND_TUNNEL
));
697 if (!ifname_valid(rvalue
)) {
698 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
699 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
703 name
= strdup(rvalue
);
707 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
711 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
713 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
714 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
716 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
717 "NetDev '%s' specified twice, ignoring.", name
);
724 int config_parse_domains(
726 const char *filename
,
729 unsigned section_line
,
744 if (isempty(rvalue
)) {
745 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
746 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
752 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
756 r
= extract_first_word(&p
, &w
, NULL
, 0);
758 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
759 "Failed to extract search or route domain, ignoring: %s", rvalue
);
765 is_route
= w
[0] == '~';
766 domain
= is_route
? w
+ 1 : w
;
768 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
769 /* If the root domain appears as is, or the special token "*" is found, we'll
770 * consider this as routing domain, unconditionally. */
772 domain
= "."; /* make sure we don't allow empty strings, thus write the root
775 r
= dns_name_normalize(domain
, 0, &normalized
);
777 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
778 "'%s' is not a valid domain name, ignoring.", domain
);
784 if (is_localhost(domain
)) {
785 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
786 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
792 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
793 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
797 r
= ordered_set_put_strdup(*set
, domain
);
805 int config_parse_ipv4ll(
807 const char *filename
,
810 unsigned section_line
,
817 AddressFamilyBoolean
*link_local
= data
;
824 /* Note that this is mostly like
825 * config_parse_address_family_boolean(), except that it
826 * applies only to IPv4 */
828 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, parse_boolean(rvalue
));
833 int config_parse_dhcp(
835 const char *filename
,
838 unsigned section_line
,
845 AddressFamilyBoolean
*dhcp
= data
, s
;
852 /* Note that this is mostly like
853 * config_parse_address_family_boolean(), except that it
854 * understands some old names for the enum values */
856 s
= address_family_boolean_from_string(rvalue
);
859 /* Previously, we had a slightly different enum here,
860 * support its values for compatbility. */
862 if (streq(rvalue
, "none"))
863 s
= ADDRESS_FAMILY_NO
;
864 else if (streq(rvalue
, "v4"))
865 s
= ADDRESS_FAMILY_IPV4
;
866 else if (streq(rvalue
, "v6"))
867 s
= ADDRESS_FAMILY_IPV6
;
868 else if (streq(rvalue
, "both"))
869 s
= ADDRESS_FAMILY_YES
;
871 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
872 "Failed to parse DHCP option, ignoring: %s", rvalue
);
876 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
877 "DHCP=%s is deprecated, please use DHCP=%s instead.",
878 rvalue
, address_family_boolean_to_string(s
));
885 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
886 [DHCP_CLIENT_ID_MAC
] = "mac",
887 [DHCP_CLIENT_ID_DUID
] = "duid",
888 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
891 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
892 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
893 "Failed to parse client identifier type");
895 int config_parse_ipv6token(
897 const char *filename
,
900 unsigned section_line
,
907 union in_addr_union buffer
;
908 struct in6_addr
*token
= data
;
916 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
918 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
919 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
923 if (in_addr_is_null(AF_INET6
, &buffer
)) {
924 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
925 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
929 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
930 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
931 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
940 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
941 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
942 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
943 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
946 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
948 int config_parse_ipv6_privacy_extensions(
950 const char *filename
,
953 unsigned section_line
,
960 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
966 assert(ipv6_privacy_extensions
);
968 /* Our enum shall be a superset of booleans, hence first try
969 * to parse as boolean, and then as enum */
971 k
= parse_boolean(rvalue
);
973 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
975 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
977 IPv6PrivacyExtensions s
;
979 s
= ipv6_privacy_extensions_from_string(rvalue
);
982 if (streq(rvalue
, "kernel"))
983 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
985 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
986 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
991 *ipv6_privacy_extensions
= s
;
997 int config_parse_hostname(
999 const char *filename
,
1001 const char *section
,
1002 unsigned section_line
,
1009 _cleanup_free_
char *hn
= NULL
;
1010 char **hostname
= data
;
1017 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1021 if (!hostname_is_valid(hn
, false)) {
1022 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1023 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1027 r
= dns_name_is_valid(hn
);
1029 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1030 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1034 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1035 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1039 return free_and_replace(*hostname
, hn
);
1042 int config_parse_timezone(
1044 const char *filename
,
1046 const char *section
,
1047 unsigned section_line
,
1054 _cleanup_free_
char *tz
= NULL
;
1055 char **datap
= data
;
1062 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1066 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1067 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1068 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1072 return free_and_replace(*datap
, tz
);
1075 int config_parse_dhcp_server_dns(
1077 const char *filename
,
1079 const char *section
,
1080 unsigned section_line
,
1088 const char *p
= rvalue
;
1096 _cleanup_free_
char *w
= NULL
;
1097 struct in_addr a
, *m
;
1099 r
= extract_first_word(&p
, &w
, NULL
, 0);
1103 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1104 "Failed to extract word, ignoring: %s", rvalue
);
1110 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1111 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1112 "Failed to parse DNS server address, ignoring: %s", w
);
1116 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1120 m
[n
->n_dhcp_server_dns
++] = a
;
1121 n
->dhcp_server_dns
= m
;
1127 int config_parse_radv_dns(
1129 const char *filename
,
1131 const char *section
,
1132 unsigned section_line
,
1140 const char *p
= rvalue
;
1148 _cleanup_free_
char *w
= NULL
;
1149 union in_addr_union a
;
1151 r
= extract_first_word(&p
, &w
, NULL
, 0);
1155 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1156 "Failed to extract word, ignoring: %s", rvalue
);
1162 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1165 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1169 m
[n
->n_router_dns
++] = a
.in6
;
1173 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1174 "Failed to parse DNS server address, ignoring: %s", w
);
1180 int config_parse_radv_search_domains(
1182 const char *filename
,
1184 const char *section
,
1185 unsigned section_line
,
1193 const char *p
= rvalue
;
1201 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1203 r
= extract_first_word(&p
, &w
, NULL
, 0);
1207 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1208 "Failed to extract word, ignoring: %s", rvalue
);
1214 r
= dns_name_apply_idna(w
, &idna
);
1216 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1217 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1220 /* transfer ownership to simplify subsequent operations */
1223 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1227 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1235 int config_parse_dhcp_server_ntp(
1237 const char *filename
,
1239 const char *section
,
1240 unsigned section_line
,
1248 const char *p
= rvalue
;
1256 _cleanup_free_
char *w
= NULL
;
1257 struct in_addr a
, *m
;
1259 r
= extract_first_word(&p
, &w
, NULL
, 0);
1263 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1264 "Failed to extract word, ignoring: %s", rvalue
);
1270 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1271 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1272 "Failed to parse NTP server address, ignoring: %s", w
);
1276 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1280 m
[n
->n_dhcp_server_ntp
++] = a
;
1281 n
->dhcp_server_ntp
= m
;
1285 int config_parse_dns(
1287 const char *filename
,
1289 const char *section
,
1290 unsigned section_line
,
1297 Network
*n
= userdata
;
1305 _cleanup_free_
char *w
= NULL
;
1306 union in_addr_union a
;
1307 struct in_addr_data
*m
;
1310 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1314 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1315 "Invalid syntax, ignoring: %s", rvalue
);
1321 r
= in_addr_from_string_auto(w
, &family
, &a
);
1323 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1324 "Failed to parse dns server address, ignoring: %s", w
);
1328 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1332 m
[n
->n_dns
++] = (struct in_addr_data
) {
1343 int config_parse_dnssec_negative_trust_anchors(
1345 const char *filename
,
1347 const char *section
,
1348 unsigned section_line
,
1355 const char *p
= rvalue
;
1363 if (isempty(rvalue
)) {
1364 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1369 _cleanup_free_
char *w
= NULL
;
1371 r
= extract_first_word(&p
, &w
, NULL
, 0);
1373 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1374 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1380 r
= dns_name_is_valid(w
);
1382 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1383 "%s is not a valid domain name, ignoring.", w
);
1387 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1391 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1401 int config_parse_ntp(
1403 const char *filename
,
1405 const char *section
,
1406 unsigned section_line
,
1420 if (isempty(rvalue
)) {
1426 _cleanup_free_
char *w
= NULL
;
1428 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1432 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1433 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1439 r
= dns_name_is_valid_or_address(w
);
1441 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1442 "%s is not a valid domain name or IP address, ignoring.", w
);
1446 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1447 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1448 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1449 MAX_NTP_SERVERS
, w
);
1453 r
= strv_consume(l
, TAKE_PTR(w
));
1461 int config_parse_dhcp_user_class(
1463 const char *filename
,
1465 const char *section
,
1466 unsigned section_line
,
1480 if (isempty(rvalue
)) {
1486 _cleanup_free_
char *w
= NULL
;
1488 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1492 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1493 "Failed to split user classes option, ignoring: %s", rvalue
);
1499 if (strlen(w
) > 255) {
1500 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1501 "%s length is not in the range 1-255, ignoring.", w
);
1505 r
= strv_push(l
, w
);
1515 int config_parse_section_route_table(
1517 const char *filename
,
1519 const char *section
,
1520 unsigned section_line
,
1527 Network
*network
= data
;
1536 r
= safe_atou32(rvalue
, &rt
);
1538 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1539 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1543 if (streq_ptr(section
, "DHCP")) {
1544 network
->dhcp_route_table
= rt
;
1545 network
->dhcp_route_table_set
= true;
1546 } else { /* section is IPv6AcceptRA */
1547 network
->ipv6_accept_ra_route_table
= rt
;
1548 network
->ipv6_accept_ra_route_table_set
= true;
1554 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1555 "Failed to parse DHCP use domains setting");
1557 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1558 [DHCP_USE_DOMAINS_NO
] = "no",
1559 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1560 [DHCP_USE_DOMAINS_YES
] = "yes",
1563 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1565 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1567 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1568 [LLDP_MODE_NO
] = "no",
1569 [LLDP_MODE_YES
] = "yes",
1570 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1573 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
1575 int config_parse_iaid(const char *unit
,
1576 const char *filename
,
1578 const char *section
,
1579 unsigned section_line
,
1585 Network
*network
= data
;
1594 r
= safe_atou32(rvalue
, &iaid
);
1596 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1597 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1601 network
->iaid
= iaid
;
1602 network
->iaid_set
= true;