1 /* SPDX-License-Identifier: LGPL-2.1+ */
4 #include <netinet/in.h>
5 #include <linux/netdevice.h>
7 #include "alloc-util.h"
8 #include "conf-files.h"
9 #include "conf-parser.h"
10 #include "dns-domain.h"
12 #include "hostname-util.h"
13 #include "in-addr-util.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
,
108 NETDEV_KIND_ERSPAN
)))
109 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
110 "%s: NetDev %s is not a %s, ignoring assignment",
111 network
->filename
, name
, kind_string
);
113 *ret_netdev
= netdev_ref(netdev
);
117 static int network_resolve_stacked_netdevs(Network
*network
) {
124 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
125 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
127 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
131 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
135 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
137 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
138 network
->filename
, (const char *) name
);
146 int network_verify(Network
*network
) {
147 Address
*address
, *address_next
;
148 Route
*route
, *route_next
;
149 FdbEntry
*fdb
, *fdb_next
;
150 Neighbor
*neighbor
, *neighbor_next
;
151 AddressLabel
*label
, *label_next
;
152 Prefix
*prefix
, *prefix_next
;
153 RoutingPolicyRule
*rule
, *rule_next
;
156 assert(network
->filename
);
158 if (set_isempty(network
->match_mac
) && strv_isempty(network
->match_path
) &&
159 strv_isempty(network
->match_driver
) && strv_isempty(network
->match_type
) &&
160 strv_isempty(network
->match_name
) && !network
->conditions
)
161 log_warning("%s: No valid settings found in the [Match] section. "
162 "The file will match all interfaces. "
163 "If that is intended, please add Name=* in the [Match] section.",
166 /* skip out early if configuration does not match the environment */
167 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
168 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
169 "%s: Conditions in the file do not match the system environment, skipping.",
172 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
173 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
174 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
175 (void) network_resolve_stacked_netdevs(network
);
177 /* Free unnecessary entries. */
178 network
->bond_name
= mfree(network
->bond_name
);
179 network
->bridge_name
= mfree(network
->bridge_name
);
180 network
->vrf_name
= mfree(network
->vrf_name
);
181 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
184 /* Bonding slave does not support addressing. */
185 if (network
->ipv6_accept_ra
> 0) {
186 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
188 network
->ipv6_accept_ra
= 0;
190 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
191 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
193 network
->link_local
= ADDRESS_FAMILY_NO
;
195 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
196 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
198 network
->dhcp
= ADDRESS_FAMILY_NO
;
200 if (network
->dhcp_server
) {
201 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
203 network
->dhcp_server
= false;
205 if (network
->n_static_addresses
> 0) {
206 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
208 while ((address
= network
->static_addresses
))
209 address_free(address
);
211 if (network
->n_static_routes
> 0) {
212 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
214 while ((route
= network
->static_routes
))
219 if (network
->link_local
< 0)
220 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
222 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
223 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
224 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
225 "Disabling the fallback assignment.", network
->filename
);
226 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
229 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
230 network
->ipv6_accept_ra
= false;
232 /* IPMasquerade=yes implies IPForward=yes */
233 if (network
->ip_masquerade
)
234 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
236 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
237 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
238 "Disabling UseMTU=.", network
->filename
);
239 network
->dhcp_use_mtu
= false;
242 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
243 if (address_section_verify(address
) < 0)
244 address_free(address
);
246 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
247 if (route_section_verify(route
, network
) < 0)
250 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
251 if (section_is_invalid(fdb
->section
))
254 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
255 if (section_is_invalid(neighbor
->section
))
256 neighbor_free(neighbor
);
258 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
259 if (section_is_invalid(label
->section
))
260 address_label_free(label
);
262 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
263 if (section_is_invalid(prefix
->section
))
266 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
267 if (section_is_invalid(rule
->section
))
268 routing_policy_rule_free(rule
);
273 int network_load_one(Manager
*manager
, const char *filename
) {
274 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
275 _cleanup_(network_unrefp
) Network
*network
= NULL
;
276 _cleanup_fclose_
FILE *file
= NULL
;
277 const char *dropin_dirname
;
284 file
= fopen(filename
, "re");
292 if (null_or_empty_fd(fileno(file
))) {
293 log_debug("Skipping empty file: %s", filename
);
297 fname
= strdup(filename
);
301 name
= strdup(basename(filename
));
305 d
= strrchr(name
, '.');
311 dropin_dirname
= strjoina(name
, ".network.d");
313 network
= new(Network
, 1);
317 *network
= (Network
) {
318 .filename
= TAKE_PTR(fname
),
319 .name
= TAKE_PTR(name
),
324 .required_for_online
= true,
325 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
326 .dhcp
= ADDRESS_FAMILY_NO
,
327 .dhcp_use_ntp
= true,
328 .dhcp_use_dns
= true,
329 .dhcp_use_hostname
= true,
330 .dhcp_use_routes
= true,
331 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
332 .dhcp_send_hostname
= true,
333 /* To enable/disable RFC7844 Anonymity Profiles */
334 .dhcp_anonymize
= false,
335 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
336 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
337 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
338 .dhcp_route_table
= RT_TABLE_MAIN
,
339 .dhcp_route_table_set
= false,
340 /* NOTE: from man: UseMTU=... Defaults to false*/
341 .dhcp_use_mtu
= false,
342 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
343 .dhcp_use_timezone
= false,
344 .rapid_commit
= true,
346 .dhcp_server_emit_dns
= true,
347 .dhcp_server_emit_ntp
= true,
348 .dhcp_server_emit_router
= true,
349 .dhcp_server_emit_timezone
= true,
351 .router_emit_dns
= true,
352 .router_emit_domains
= true,
357 .allow_port_to_be_root
= -1,
359 .multicast_flood
= -1,
360 .multicast_to_unicast
= -1,
361 .neighbor_suppression
= -1,
363 .bridge_proxy_arp
= -1,
364 .bridge_proxy_arp_wifi
= -1,
365 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
366 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
368 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
370 .dns_default_route
= -1,
371 .llmnr
= RESOLVE_SUPPORT_YES
,
372 .mdns
= RESOLVE_SUPPORT_NO
,
373 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
374 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
376 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
377 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
379 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
380 .ipv6_accept_ra
= -1,
381 .ipv6_dad_transmits
= -1,
382 .ipv6_hop_limit
= -1,
383 .ipv6_proxy_ndp
= -1,
384 .duid
.type
= _DUID_TYPE_INVALID
,
389 .ipv6_accept_ra_use_dns
= true,
390 .ipv6_accept_ra_use_autonomous_prefix
= true,
391 .ipv6_accept_ra_use_onlink_prefix
= true,
392 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
393 .ipv6_accept_ra_route_table_set
= false,
395 .can_triple_sampling
= -1,
398 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
405 "RoutingPolicyRule\0"
408 "DHCPv4\0" /* compat */
411 "IPv6NDPProxyAddress\0"
415 "IPv6PrefixDelegation\0"
418 config_item_perf_lookup
, network_network_gperf_lookup
,
419 CONFIG_PARSE_WARN
, network
);
423 network_apply_anonymize_if_set(network
);
425 r
= network_add_ipv4ll_route(network
);
427 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
429 r
= network_add_default_route_on_device(network
);
431 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
434 r
= ordered_hashmap_ensure_allocated(&manager
->networks
, &string_hash_ops
);
438 r
= ordered_hashmap_put(manager
->networks
, network
->name
, network
);
442 if (network_verify(network
) < 0)
449 int network_load(Manager
*manager
) {
450 _cleanup_strv_free_
char **files
= NULL
;
456 ordered_hashmap_clear_with_destructor(manager
->networks
, network_unref
);
458 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
460 return log_error_errno(r
, "Failed to enumerate network files: %m");
462 STRV_FOREACH(f
, files
) {
463 r
= network_load_one(manager
, *f
);
471 static Network
*network_free(Network
*network
) {
472 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
473 RoutingPolicyRule
*rule
;
484 free(network
->filename
);
486 set_free_free(network
->match_mac
);
487 strv_free(network
->match_path
);
488 strv_free(network
->match_driver
);
489 strv_free(network
->match_type
);
490 strv_free(network
->match_name
);
491 condition_free_list(network
->conditions
);
493 free(network
->description
);
494 free(network
->dhcp_vendor_class_identifier
);
495 strv_free(network
->dhcp_user_class
);
496 free(network
->dhcp_hostname
);
497 set_free(network
->dhcp_black_listed_ip
);
500 strv_free(network
->ntp
);
502 ordered_set_free_free(network
->search_domains
);
503 ordered_set_free_free(network
->route_domains
);
504 strv_free(network
->bind_carrier
);
506 ordered_set_free_free(network
->router_search_domains
);
507 free(network
->router_dns
);
509 free(network
->bridge_name
);
510 free(network
->bond_name
);
511 free(network
->vrf_name
);
512 hashmap_free_free_key(network
->stacked_netdev_names
);
513 netdev_unref(network
->bridge
);
514 netdev_unref(network
->bond
);
515 netdev_unref(network
->vrf
);
516 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
518 while ((route
= network
->static_routes
))
521 while ((address
= network
->static_addresses
))
522 address_free(address
);
524 while ((fdb_entry
= network
->static_fdb_entries
))
525 fdb_entry_free(fdb_entry
);
527 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
528 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
530 while ((neighbor
= network
->neighbors
))
531 neighbor_free(neighbor
);
533 while ((label
= network
->address_labels
))
534 address_label_free(label
);
536 while ((prefix
= network
->static_prefixes
))
539 while ((rule
= network
->rules
))
540 routing_policy_rule_free(rule
);
542 hashmap_free(network
->addresses_by_section
);
543 hashmap_free(network
->routes_by_section
);
544 hashmap_free(network
->fdb_entries_by_section
);
545 hashmap_free(network
->neighbors_by_section
);
546 hashmap_free(network
->address_labels_by_section
);
547 hashmap_free(network
->prefixes_by_section
);
548 hashmap_free(network
->rules_by_section
);
550 if (network
->manager
) {
551 if (network
->manager
->networks
&& network
->name
)
552 ordered_hashmap_remove(network
->manager
->networks
, network
->name
);
554 if (network
->manager
->duids_requesting_uuid
)
555 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
560 free(network
->dhcp_server_timezone
);
561 free(network
->dhcp_server_dns
);
562 free(network
->dhcp_server_ntp
);
564 set_free_free(network
->dnssec_negative_trust_anchors
);
566 return mfree(network
);
569 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
571 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
578 network
= ordered_hashmap_get(manager
->networks
, name
);
587 int network_get(Manager
*manager
, sd_device
*device
,
588 const char *ifname
, const struct ether_addr
*address
,
590 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
598 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
600 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
602 (void) sd_device_get_devtype(device
, &devtype
);
605 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
606 if (net_match_config(network
->match_mac
, network
->match_path
,
607 network
->match_driver
, network
->match_type
,
609 address
, path
, driver
, devtype
, ifname
)) {
610 if (network
->match_name
&& device
) {
612 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
614 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
615 (void) safe_atou8(attr
, &name_assign_type
);
617 if (name_assign_type
== NET_NAME_ENUM
)
618 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
619 ifname
, network
->filename
);
621 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
623 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
634 int network_apply(Network
*network
, Link
*link
) {
638 link
->network
= network_ref(network
);
640 if (network
->n_dns
> 0 ||
641 !strv_isempty(network
->ntp
) ||
642 !ordered_set_isempty(network
->search_domains
) ||
643 !ordered_set_isempty(network
->route_domains
))
649 bool network_has_static_ipv6_addresses(Network
*network
) {
654 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
655 if (address
->family
== AF_INET6
)
662 int config_parse_stacked_netdev(const char *unit
,
663 const char *filename
,
666 unsigned section_line
,
672 _cleanup_free_
char *name
= NULL
;
673 NetDevKind kind
= ltype
;
682 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
683 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
684 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
));
686 if (!ifname_valid(rvalue
)) {
687 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
688 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
692 name
= strdup(rvalue
);
696 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
700 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
702 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
703 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
705 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
706 "NetDev '%s' specified twice, ignoring.", name
);
713 int config_parse_domains(
715 const char *filename
,
718 unsigned section_line
,
733 if (isempty(rvalue
)) {
734 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
735 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
741 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
745 r
= extract_first_word(&p
, &w
, NULL
, 0);
747 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
748 "Failed to extract search or route domain, ignoring: %s", rvalue
);
754 is_route
= w
[0] == '~';
755 domain
= is_route
? w
+ 1 : w
;
757 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
758 /* If the root domain appears as is, or the special token "*" is found, we'll
759 * consider this as routing domain, unconditionally. */
761 domain
= "."; /* make sure we don't allow empty strings, thus write the root
764 r
= dns_name_normalize(domain
, 0, &normalized
);
766 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
767 "'%s' is not a valid domain name, ignoring.", domain
);
773 if (is_localhost(domain
)) {
774 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
775 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
781 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
782 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
786 r
= ordered_set_put_strdup(*set
, domain
);
794 int config_parse_ipv4ll(
796 const char *filename
,
799 unsigned section_line
,
806 AddressFamilyBoolean
*link_local
= data
;
814 /* Note that this is mostly like
815 * config_parse_address_family_boolean(), except that it
816 * applies only to IPv4 */
818 r
= parse_boolean(rvalue
);
820 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
821 "Failed to parse %s=%s, ignoring assignment. "
822 "Note that the setting %s= is deprecated, please use LinkLocalAddressing= instead.",
823 lvalue
, rvalue
, lvalue
);
827 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, r
);
829 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
830 "%s=%s is deprecated, please use LinkLocalAddressing=%s instead.",
831 lvalue
, rvalue
, address_family_boolean_to_string(*link_local
));
836 int config_parse_dhcp(
838 const char *filename
,
841 unsigned section_line
,
848 AddressFamilyBoolean
*dhcp
= data
, s
;
855 /* Note that this is mostly like
856 * config_parse_address_family_boolean(), except that it
857 * understands some old names for the enum values */
859 s
= address_family_boolean_from_string(rvalue
);
862 /* Previously, we had a slightly different enum here,
863 * support its values for compatibility. */
865 if (streq(rvalue
, "none"))
866 s
= ADDRESS_FAMILY_NO
;
867 else if (streq(rvalue
, "v4"))
868 s
= ADDRESS_FAMILY_IPV4
;
869 else if (streq(rvalue
, "v6"))
870 s
= ADDRESS_FAMILY_IPV6
;
871 else if (streq(rvalue
, "both"))
872 s
= ADDRESS_FAMILY_YES
;
874 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
875 "Failed to parse DHCP option, ignoring: %s", rvalue
);
879 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
880 "DHCP=%s is deprecated, please use DHCP=%s instead.",
881 rvalue
, address_family_boolean_to_string(s
));
888 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
889 [DHCP_CLIENT_ID_MAC
] = "mac",
890 [DHCP_CLIENT_ID_DUID
] = "duid",
891 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
894 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
895 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
896 "Failed to parse client identifier type");
898 int config_parse_ipv6token(
900 const char *filename
,
903 unsigned section_line
,
910 union in_addr_union buffer
;
911 struct in6_addr
*token
= data
;
919 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
921 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
922 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
926 if (in_addr_is_null(AF_INET6
, &buffer
)) {
927 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
928 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
932 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
933 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
934 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
943 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
944 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
945 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
946 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
949 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
951 int config_parse_ipv6_privacy_extensions(
953 const char *filename
,
956 unsigned section_line
,
963 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
969 assert(ipv6_privacy_extensions
);
971 /* Our enum shall be a superset of booleans, hence first try
972 * to parse as boolean, and then as enum */
974 k
= parse_boolean(rvalue
);
976 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
978 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
980 IPv6PrivacyExtensions s
;
982 s
= ipv6_privacy_extensions_from_string(rvalue
);
985 if (streq(rvalue
, "kernel"))
986 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
988 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
989 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
994 *ipv6_privacy_extensions
= s
;
1000 int config_parse_hostname(
1002 const char *filename
,
1004 const char *section
,
1005 unsigned section_line
,
1012 _cleanup_free_
char *hn
= NULL
;
1013 char **hostname
= data
;
1020 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1024 if (!hostname_is_valid(hn
, false)) {
1025 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1026 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1030 r
= dns_name_is_valid(hn
);
1032 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1033 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1037 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1038 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1042 return free_and_replace(*hostname
, hn
);
1045 int config_parse_timezone(
1047 const char *filename
,
1049 const char *section
,
1050 unsigned section_line
,
1057 _cleanup_free_
char *tz
= NULL
;
1058 char **datap
= data
;
1065 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1069 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1070 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1071 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1075 return free_and_replace(*datap
, tz
);
1078 int config_parse_dhcp_server_dns(
1080 const char *filename
,
1082 const char *section
,
1083 unsigned section_line
,
1091 const char *p
= rvalue
;
1099 _cleanup_free_
char *w
= NULL
;
1100 union in_addr_union a
;
1103 r
= extract_first_word(&p
, &w
, NULL
, 0);
1107 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1108 "Failed to extract word, ignoring: %s", rvalue
);
1114 r
= in_addr_from_string(AF_INET
, w
, &a
);
1116 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1117 "Failed to parse DNS server address '%s', ignoring assignment: %m", w
);
1121 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1125 m
[n
->n_dhcp_server_dns
++] = a
.in
;
1126 n
->dhcp_server_dns
= m
;
1132 int config_parse_radv_dns(
1134 const char *filename
,
1136 const char *section
,
1137 unsigned section_line
,
1145 const char *p
= rvalue
;
1153 _cleanup_free_
char *w
= NULL
;
1154 union in_addr_union a
;
1156 r
= extract_first_word(&p
, &w
, NULL
, 0);
1160 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1161 "Failed to extract word, ignoring: %s", rvalue
);
1167 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1170 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1174 m
[n
->n_router_dns
++] = a
.in6
;
1178 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1179 "Failed to parse DNS server address, ignoring: %s", w
);
1185 int config_parse_radv_search_domains(
1187 const char *filename
,
1189 const char *section
,
1190 unsigned section_line
,
1198 const char *p
= rvalue
;
1206 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1208 r
= extract_first_word(&p
, &w
, NULL
, 0);
1212 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1213 "Failed to extract word, ignoring: %s", rvalue
);
1219 r
= dns_name_apply_idna(w
, &idna
);
1221 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1222 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1225 /* transfer ownership to simplify subsequent operations */
1228 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1232 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1240 int config_parse_dhcp_server_ntp(
1242 const char *filename
,
1244 const char *section
,
1245 unsigned section_line
,
1253 const char *p
= rvalue
;
1261 _cleanup_free_
char *w
= NULL
;
1262 union in_addr_union a
;
1265 r
= extract_first_word(&p
, &w
, NULL
, 0);
1269 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1270 "Failed to extract word, ignoring: %s", rvalue
);
1276 r
= in_addr_from_string(AF_INET
, w
, &a
);
1278 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1279 "Failed to parse NTP server address '%s', ignoring: %m", w
);
1283 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1287 m
[n
->n_dhcp_server_ntp
++] = a
.in
;
1288 n
->dhcp_server_ntp
= m
;
1292 int config_parse_dns(
1294 const char *filename
,
1296 const char *section
,
1297 unsigned section_line
,
1304 Network
*n
= userdata
;
1312 _cleanup_free_
char *w
= NULL
;
1313 union in_addr_union a
;
1314 struct in_addr_data
*m
;
1317 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1321 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1322 "Invalid syntax, ignoring: %s", rvalue
);
1328 r
= in_addr_from_string_auto(w
, &family
, &a
);
1330 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1331 "Failed to parse dns server address, ignoring: %s", w
);
1335 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1339 m
[n
->n_dns
++] = (struct in_addr_data
) {
1350 int config_parse_dnssec_negative_trust_anchors(
1352 const char *filename
,
1354 const char *section
,
1355 unsigned section_line
,
1362 const char *p
= rvalue
;
1370 if (isempty(rvalue
)) {
1371 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1376 _cleanup_free_
char *w
= NULL
;
1378 r
= extract_first_word(&p
, &w
, NULL
, 0);
1380 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1381 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1387 r
= dns_name_is_valid(w
);
1389 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1390 "%s is not a valid domain name, ignoring.", w
);
1394 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1398 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1408 int config_parse_ntp(
1410 const char *filename
,
1412 const char *section
,
1413 unsigned section_line
,
1427 if (isempty(rvalue
)) {
1433 _cleanup_free_
char *w
= NULL
;
1435 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1439 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1440 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1446 r
= dns_name_is_valid_or_address(w
);
1448 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1449 "%s is not a valid domain name or IP address, ignoring.", w
);
1453 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1454 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1455 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1456 MAX_NTP_SERVERS
, w
);
1460 r
= strv_consume(l
, TAKE_PTR(w
));
1468 int config_parse_dhcp_user_class(
1470 const char *filename
,
1472 const char *section
,
1473 unsigned section_line
,
1487 if (isempty(rvalue
)) {
1493 _cleanup_free_
char *w
= NULL
;
1495 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1499 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1500 "Failed to split user classes option, ignoring: %s", rvalue
);
1506 if (strlen(w
) > 255) {
1507 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1508 "%s length is not in the range 1-255, ignoring.", w
);
1512 r
= strv_push(l
, w
);
1522 int config_parse_section_route_table(
1524 const char *filename
,
1526 const char *section
,
1527 unsigned section_line
,
1534 Network
*network
= data
;
1543 r
= safe_atou32(rvalue
, &rt
);
1545 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1546 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1550 if (streq_ptr(section
, "DHCP")) {
1551 network
->dhcp_route_table
= rt
;
1552 network
->dhcp_route_table_set
= true;
1553 } else { /* section is IPv6AcceptRA */
1554 network
->ipv6_accept_ra_route_table
= rt
;
1555 network
->ipv6_accept_ra_route_table_set
= true;
1561 int config_parse_dhcp_max_attempts(
1563 const char *filename
,
1565 const char *section
,
1566 unsigned section_line
,
1573 Network
*network
= data
;
1581 if (isempty(rvalue
)) {
1582 network
->dhcp_max_attempts
= 0;
1586 if (streq(rvalue
, "infinity")) {
1587 network
->dhcp_max_attempts
= (uint64_t) -1;
1591 r
= safe_atou64(rvalue
, &a
);
1593 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1594 "Failed to parse DHCP maximum attempts, ignoring: %s", rvalue
);
1599 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1600 "%s= must be positive integer or 'infinity', ignoring: %s", lvalue
, rvalue
);
1604 network
->dhcp_max_attempts
= a
;
1609 int config_parse_dhcp_black_listed_ip_address(
1611 const char *filename
,
1613 const char *section
,
1614 unsigned section_line
,
1621 Network
*network
= data
;
1630 if (isempty(rvalue
)) {
1631 network
->dhcp_black_listed_ip
= set_free(network
->dhcp_black_listed_ip
);
1635 for (p
= rvalue
;;) {
1636 _cleanup_free_
char *n
= NULL
;
1637 union in_addr_union ip
;
1639 r
= extract_first_word(&p
, &n
, NULL
, 0);
1641 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1642 "Failed to parse DHCP black listed ip address, ignoring assignment: %s",
1649 r
= in_addr_from_string(AF_INET
, n
, &ip
);
1651 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1652 "DHCP black listed ip address is invalid, ignoring assignment: %s", n
);
1656 r
= set_ensure_allocated(&network
->dhcp_black_listed_ip
, NULL
);
1660 r
= set_put(network
->dhcp_black_listed_ip
, UINT32_TO_PTR(ip
.in
.s_addr
));
1662 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1663 "DHCP black listed ip address is duplicated, ignoring assignment: %s", n
);
1667 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1668 "Failed to store DHCP black listed ip address '%s', ignoring assignment: %m", n
);
1674 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1675 "Failed to parse DHCP use domains setting");
1677 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1678 [DHCP_USE_DOMAINS_NO
] = "no",
1679 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1680 [DHCP_USE_DOMAINS_YES
] = "yes",
1683 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1685 int config_parse_iaid(const char *unit
,
1686 const char *filename
,
1688 const char *section
,
1689 unsigned section_line
,
1695 Network
*network
= data
;
1704 r
= safe_atou32(rvalue
, &iaid
);
1706 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1707 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1711 network
->iaid
= iaid
;
1712 network
->iaid_set
= true;
1717 int config_parse_required_for_online(
1719 const char *filename
,
1721 const char *section
,
1722 unsigned section_line
,
1729 Network
*network
= data
;
1730 LinkOperationalState s
;
1731 bool required
= true;
1734 if (isempty(rvalue
)) {
1735 network
->required_for_online
= true;
1736 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1740 s
= link_operstate_from_string(rvalue
);
1742 r
= parse_boolean(rvalue
);
1744 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1745 "Failed to parse %s= setting, ignoring assignment: %s",
1751 s
= LINK_OPERSTATE_DEGRADED
;
1754 network
->required_for_online
= required
;
1755 network
->required_operstate_for_online
= s
;