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
) && strv_isempty(network
->match_property
) &&
161 !network
->conditions
)
162 log_warning("%s: No valid settings found in the [Match] section. "
163 "The file will match all interfaces. "
164 "If that is intended, please add Name=* in the [Match] section.",
167 /* skip out early if configuration does not match the environment */
168 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
169 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
170 "%s: Conditions in the file do not match the system environment, skipping.",
173 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
174 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
175 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
176 (void) network_resolve_stacked_netdevs(network
);
178 /* Free unnecessary entries. */
179 network
->bond_name
= mfree(network
->bond_name
);
180 network
->bridge_name
= mfree(network
->bridge_name
);
181 network
->vrf_name
= mfree(network
->vrf_name
);
182 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
185 /* Bonding slave does not support addressing. */
186 if (network
->ipv6_accept_ra
> 0) {
187 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
189 network
->ipv6_accept_ra
= 0;
191 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
192 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
194 network
->link_local
= ADDRESS_FAMILY_NO
;
196 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
197 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
199 network
->dhcp
= ADDRESS_FAMILY_NO
;
201 if (network
->dhcp_server
) {
202 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
204 network
->dhcp_server
= false;
206 if (network
->n_static_addresses
> 0) {
207 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
209 while ((address
= network
->static_addresses
))
210 address_free(address
);
212 if (network
->n_static_routes
> 0) {
213 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
215 while ((route
= network
->static_routes
))
220 if (network
->link_local
< 0)
221 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
223 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
224 if (network
->ipv6_accept_ra
> 0) {
225 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
226 "Disabling IPv6AcceptRA=.", network
->filename
);
227 network
->ipv6_accept_ra
= false;
230 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
231 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
232 "Disabling DHCPv6 client.", network
->filename
);
233 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
236 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
237 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
238 "Disabling IPv6PrefixDelegation=.", network
->filename
);
239 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
243 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
244 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
245 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
246 "Disabling the fallback assignment.", network
->filename
);
247 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
250 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
251 network
->ipv6_accept_ra
= false;
253 /* IPMasquerade=yes implies IPForward=yes */
254 if (network
->ip_masquerade
)
255 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
257 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
258 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
259 "Disabling UseMTU=.", network
->filename
);
260 network
->dhcp_use_mtu
= false;
263 if (network
->dhcp_critical
>= 0) {
264 if (network
->keep_configuration
>= 0)
265 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
266 "Ignoring CriticalConnection=.", network
->filename
);
267 else if (network
->dhcp_critical
)
268 /* CriticalConnection=yes also preserve foreign static configurations. */
269 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
271 /* For backward compatibility, we do not release DHCP addresses on manager stop. */
272 network
->keep_configuration
= KEEP_CONFIGURATION_DHCP_ON_STOP
;
275 if (network
->keep_configuration
< 0)
276 /* For backward compatibility, we do not release DHCP addresses on manager stop. */
277 network
->keep_configuration
= KEEP_CONFIGURATION_DHCP_ON_STOP
;
279 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
280 if (address_section_verify(address
) < 0)
281 address_free(address
);
283 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
284 if (route_section_verify(route
, network
) < 0)
287 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
288 if (section_is_invalid(fdb
->section
))
291 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
292 if (neighbor_section_verify(neighbor
) < 0)
293 neighbor_free(neighbor
);
295 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
296 if (section_is_invalid(label
->section
))
297 address_label_free(label
);
299 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
300 if (section_is_invalid(prefix
->section
))
303 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
304 if (routing_policy_rule_section_verify(rule
) < 0)
305 routing_policy_rule_free(rule
);
310 int network_load_one(Manager
*manager
, const char *filename
) {
311 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
312 _cleanup_(network_unrefp
) Network
*network
= NULL
;
313 _cleanup_fclose_
FILE *file
= NULL
;
314 const char *dropin_dirname
;
321 file
= fopen(filename
, "re");
329 if (null_or_empty_fd(fileno(file
))) {
330 log_debug("Skipping empty file: %s", filename
);
334 fname
= strdup(filename
);
338 name
= strdup(basename(filename
));
342 d
= strrchr(name
, '.');
348 dropin_dirname
= strjoina(name
, ".network.d");
350 network
= new(Network
, 1);
354 *network
= (Network
) {
355 .filename
= TAKE_PTR(fname
),
356 .name
= TAKE_PTR(name
),
361 .required_for_online
= true,
362 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
363 .dhcp
= ADDRESS_FAMILY_NO
,
365 .dhcp_use_ntp
= true,
366 .dhcp_use_dns
= true,
367 .dhcp_use_hostname
= true,
368 .dhcp_use_routes
= true,
369 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
370 .dhcp_send_hostname
= true,
371 /* To enable/disable RFC7844 Anonymity Profiles */
372 .dhcp_anonymize
= false,
373 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
374 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
375 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
376 .dhcp_route_table
= RT_TABLE_MAIN
,
377 .dhcp_route_table_set
= false,
378 /* NOTE: from man: UseMTU=... Defaults to false*/
379 .dhcp_use_mtu
= false,
380 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
381 .dhcp_use_timezone
= false,
382 .rapid_commit
= true,
384 .dhcp6_use_ntp
= true,
385 .dhcp6_use_dns
= true,
387 .dhcp_server_emit_dns
= true,
388 .dhcp_server_emit_ntp
= true,
389 .dhcp_server_emit_router
= true,
390 .dhcp_server_emit_timezone
= true,
392 .router_emit_dns
= true,
393 .router_emit_domains
= true,
398 .allow_port_to_be_root
= -1,
400 .multicast_flood
= -1,
401 .multicast_to_unicast
= -1,
402 .neighbor_suppression
= -1,
404 .bridge_proxy_arp
= -1,
405 .bridge_proxy_arp_wifi
= -1,
406 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
407 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
409 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
411 .dns_default_route
= -1,
412 .llmnr
= RESOLVE_SUPPORT_YES
,
413 .mdns
= RESOLVE_SUPPORT_NO
,
414 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
415 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
417 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
418 .link_local
= _ADDRESS_FAMILY_INVALID
,
420 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
421 .ipv6_accept_ra
= -1,
422 .ipv6_dad_transmits
= -1,
423 .ipv6_hop_limit
= -1,
424 .ipv6_proxy_ndp
= -1,
425 .duid
.type
= _DUID_TYPE_INVALID
,
430 .ipv6_accept_ra_use_dns
= true,
431 .ipv6_accept_ra_use_autonomous_prefix
= true,
432 .ipv6_accept_ra_use_onlink_prefix
= true,
433 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
434 .ipv6_accept_ra_route_table_set
= false,
436 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
438 .can_triple_sampling
= -1,
441 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
448 "RoutingPolicyRule\0"
451 "DHCPv4\0" /* compat */
455 "IPv6NDPProxyAddress\0"
459 "IPv6PrefixDelegation\0"
462 config_item_perf_lookup
, network_network_gperf_lookup
,
463 CONFIG_PARSE_WARN
, network
);
467 network_apply_anonymize_if_set(network
);
469 r
= network_add_ipv4ll_route(network
);
471 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
473 r
= network_add_default_route_on_device(network
);
475 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
478 r
= ordered_hashmap_ensure_allocated(&manager
->networks
, &string_hash_ops
);
482 r
= ordered_hashmap_put(manager
->networks
, network
->name
, network
);
486 if (network_verify(network
) < 0)
493 int network_load(Manager
*manager
) {
494 _cleanup_strv_free_
char **files
= NULL
;
500 ordered_hashmap_clear_with_destructor(manager
->networks
, network_unref
);
502 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
504 return log_error_errno(r
, "Failed to enumerate network files: %m");
506 STRV_FOREACH(f
, files
) {
507 r
= network_load_one(manager
, *f
);
509 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
515 static Network
*network_free(Network
*network
) {
516 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
517 RoutingPolicyRule
*rule
;
528 free(network
->filename
);
530 set_free_free(network
->match_mac
);
531 strv_free(network
->match_path
);
532 strv_free(network
->match_driver
);
533 strv_free(network
->match_type
);
534 strv_free(network
->match_name
);
535 strv_free(network
->match_property
);
536 condition_free_list(network
->conditions
);
538 free(network
->description
);
539 free(network
->dhcp_vendor_class_identifier
);
540 strv_free(network
->dhcp_user_class
);
541 free(network
->dhcp_hostname
);
542 set_free(network
->dhcp_black_listed_ip
);
545 strv_free(network
->ntp
);
547 ordered_set_free_free(network
->search_domains
);
548 ordered_set_free_free(network
->route_domains
);
549 strv_free(network
->bind_carrier
);
551 ordered_set_free_free(network
->router_search_domains
);
552 free(network
->router_dns
);
553 set_free_free(network
->ndisc_black_listed_prefix
);
555 free(network
->bridge_name
);
556 free(network
->bond_name
);
557 free(network
->vrf_name
);
558 hashmap_free_free_key(network
->stacked_netdev_names
);
559 netdev_unref(network
->bridge
);
560 netdev_unref(network
->bond
);
561 netdev_unref(network
->vrf
);
562 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
564 while ((route
= network
->static_routes
))
567 while ((address
= network
->static_addresses
))
568 address_free(address
);
570 while ((fdb_entry
= network
->static_fdb_entries
))
571 fdb_entry_free(fdb_entry
);
573 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
574 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
576 while ((neighbor
= network
->neighbors
))
577 neighbor_free(neighbor
);
579 while ((label
= network
->address_labels
))
580 address_label_free(label
);
582 while ((prefix
= network
->static_prefixes
))
585 while ((rule
= network
->rules
))
586 routing_policy_rule_free(rule
);
588 hashmap_free(network
->addresses_by_section
);
589 hashmap_free(network
->routes_by_section
);
590 hashmap_free(network
->fdb_entries_by_section
);
591 hashmap_free(network
->neighbors_by_section
);
592 hashmap_free(network
->address_labels_by_section
);
593 hashmap_free(network
->prefixes_by_section
);
594 hashmap_free(network
->rules_by_section
);
596 if (network
->manager
) {
597 if (network
->manager
->networks
&& network
->name
)
598 ordered_hashmap_remove(network
->manager
->networks
, network
->name
);
600 if (network
->manager
->duids_requesting_uuid
)
601 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
606 free(network
->dhcp_server_timezone
);
607 free(network
->dhcp_server_dns
);
608 free(network
->dhcp_server_ntp
);
610 set_free_free(network
->dnssec_negative_trust_anchors
);
612 return mfree(network
);
615 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
617 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
624 network
= ordered_hashmap_get(manager
->networks
, name
);
633 int network_get(Manager
*manager
, sd_device
*device
,
634 const char *ifname
, const struct ether_addr
*address
,
642 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
643 if (net_match_config(network
->match_mac
, network
->match_path
, network
->match_driver
,
644 network
->match_type
, network
->match_name
, network
->match_property
,
645 device
, address
, ifname
)) {
646 if (network
->match_name
&& device
) {
648 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
650 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
651 (void) safe_atou8(attr
, &name_assign_type
);
653 if (name_assign_type
== NET_NAME_ENUM
)
654 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
655 ifname
, network
->filename
);
657 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
659 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
670 int network_apply(Network
*network
, Link
*link
) {
674 link
->network
= network_ref(network
);
676 if (network
->n_dns
> 0 ||
677 !strv_isempty(network
->ntp
) ||
678 !ordered_set_isempty(network
->search_domains
) ||
679 !ordered_set_isempty(network
->route_domains
))
685 bool network_has_static_ipv6_configurations(Network
*network
) {
693 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
694 if (address
->family
== AF_INET6
)
697 LIST_FOREACH(routes
, route
, network
->static_routes
)
698 if (route
->family
== AF_INET6
)
701 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
702 if (fdb
->family
== AF_INET6
)
705 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
706 if (neighbor
->family
== AF_INET6
)
709 if (!LIST_IS_EMPTY(network
->address_labels
))
712 if (!LIST_IS_EMPTY(network
->static_prefixes
))
718 int config_parse_stacked_netdev(const char *unit
,
719 const char *filename
,
722 unsigned section_line
,
728 _cleanup_free_
char *name
= NULL
;
729 NetDevKind kind
= ltype
;
738 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
739 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
740 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
743 if (!ifname_valid(rvalue
)) {
744 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
745 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
749 name
= strdup(rvalue
);
753 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
757 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
759 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
760 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
762 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
763 "NetDev '%s' specified twice, ignoring.", name
);
770 int config_parse_domains(
772 const char *filename
,
775 unsigned section_line
,
790 if (isempty(rvalue
)) {
791 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
792 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
798 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
802 r
= extract_first_word(&p
, &w
, NULL
, 0);
804 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
805 "Failed to extract search or route domain, ignoring: %s", rvalue
);
811 is_route
= w
[0] == '~';
812 domain
= is_route
? w
+ 1 : w
;
814 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
815 /* If the root domain appears as is, or the special token "*" is found, we'll
816 * consider this as routing domain, unconditionally. */
818 domain
= "."; /* make sure we don't allow empty strings, thus write the root
821 r
= dns_name_normalize(domain
, 0, &normalized
);
823 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
824 "'%s' is not a valid domain name, ignoring.", domain
);
830 if (is_localhost(domain
)) {
831 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
832 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
838 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
839 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
843 r
= ordered_set_put_strdup(*set
, domain
);
851 int config_parse_ipv6token(
853 const char *filename
,
856 unsigned section_line
,
863 union in_addr_union buffer
;
864 struct in6_addr
*token
= data
;
872 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
874 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
875 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
879 if (in_addr_is_null(AF_INET6
, &buffer
)) {
880 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
881 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
885 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
886 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
887 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
896 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
897 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
898 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
899 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
902 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
903 IPV6_PRIVACY_EXTENSIONS_YES
);
905 int config_parse_ipv6_privacy_extensions(
907 const char *filename
,
910 unsigned section_line
,
917 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
922 assert(ipv6_privacy_extensions
);
924 s
= ipv6_privacy_extensions_from_string(rvalue
);
926 if (streq(rvalue
, "kernel"))
927 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
929 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
930 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
935 *ipv6_privacy_extensions
= s
;
940 int config_parse_hostname(
942 const char *filename
,
945 unsigned section_line
,
952 _cleanup_free_
char *hn
= NULL
;
953 char **hostname
= data
;
960 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
964 if (!hostname_is_valid(hn
, false)) {
965 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
966 "Hostname is not valid, ignoring assignment: %s", rvalue
);
970 r
= dns_name_is_valid(hn
);
972 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
973 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
977 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
978 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
982 return free_and_replace(*hostname
, hn
);
985 int config_parse_timezone(
987 const char *filename
,
990 unsigned section_line
,
997 _cleanup_free_
char *tz
= NULL
;
1005 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1009 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1010 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1011 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1015 return free_and_replace(*datap
, tz
);
1018 int config_parse_dns(
1020 const char *filename
,
1022 const char *section
,
1023 unsigned section_line
,
1030 Network
*n
= userdata
;
1038 _cleanup_free_
char *w
= NULL
;
1039 union in_addr_union a
;
1040 struct in_addr_data
*m
;
1043 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1047 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1048 "Invalid syntax, ignoring: %s", rvalue
);
1054 r
= in_addr_from_string_auto(w
, &family
, &a
);
1056 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1057 "Failed to parse dns server address, ignoring: %s", w
);
1061 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1065 m
[n
->n_dns
++] = (struct in_addr_data
) {
1076 int config_parse_dnssec_negative_trust_anchors(
1078 const char *filename
,
1080 const char *section
,
1081 unsigned section_line
,
1088 const char *p
= rvalue
;
1096 if (isempty(rvalue
)) {
1097 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1102 _cleanup_free_
char *w
= NULL
;
1104 r
= extract_first_word(&p
, &w
, NULL
, 0);
1106 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1107 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1113 r
= dns_name_is_valid(w
);
1115 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1116 "%s is not a valid domain name, ignoring.", w
);
1120 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1124 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1134 int config_parse_ntp(
1136 const char *filename
,
1138 const char *section
,
1139 unsigned section_line
,
1153 if (isempty(rvalue
)) {
1159 _cleanup_free_
char *w
= NULL
;
1161 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1165 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1166 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1172 r
= dns_name_is_valid_or_address(w
);
1174 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1175 "%s is not a valid domain name or IP address, ignoring.", w
);
1179 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1180 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1181 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1182 MAX_NTP_SERVERS
, w
);
1186 r
= strv_consume(l
, TAKE_PTR(w
));
1194 int config_parse_required_for_online(
1196 const char *filename
,
1198 const char *section
,
1199 unsigned section_line
,
1206 Network
*network
= data
;
1207 LinkOperationalState s
;
1208 bool required
= true;
1211 if (isempty(rvalue
)) {
1212 network
->required_for_online
= true;
1213 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1217 s
= link_operstate_from_string(rvalue
);
1219 r
= parse_boolean(rvalue
);
1221 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1222 "Failed to parse %s= setting, ignoring assignment: %s",
1228 s
= LINK_OPERSTATE_DEGRADED
;
1231 network
->required_for_online
= required
;
1232 network
->required_operstate_for_online
= s
;
1237 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1238 "Failed to parse KeepConfiguration= setting");
1240 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1241 [KEEP_CONFIGURATION_NO
] = "no",
1242 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1243 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1244 [KEEP_CONFIGURATION_STATIC
] = "static",
1245 [KEEP_CONFIGURATION_YES
] = "yes",
1248 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);