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"
463 config_item_perf_lookup
, network_network_gperf_lookup
,
464 CONFIG_PARSE_WARN
, network
);
468 network_apply_anonymize_if_set(network
);
470 r
= network_add_ipv4ll_route(network
);
472 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
474 r
= network_add_default_route_on_device(network
);
476 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
479 r
= ordered_hashmap_ensure_allocated(&manager
->networks
, &string_hash_ops
);
483 r
= ordered_hashmap_put(manager
->networks
, network
->name
, network
);
487 if (network_verify(network
) < 0)
494 int network_load(Manager
*manager
) {
495 _cleanup_strv_free_
char **files
= NULL
;
501 ordered_hashmap_clear_with_destructor(manager
->networks
, network_unref
);
503 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
505 return log_error_errno(r
, "Failed to enumerate network files: %m");
507 STRV_FOREACH(f
, files
) {
508 r
= network_load_one(manager
, *f
);
510 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
516 static Network
*network_free(Network
*network
) {
517 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
518 RoutingPolicyRule
*rule
;
529 free(network
->filename
);
531 set_free_free(network
->match_mac
);
532 strv_free(network
->match_path
);
533 strv_free(network
->match_driver
);
534 strv_free(network
->match_type
);
535 strv_free(network
->match_name
);
536 strv_free(network
->match_property
);
537 condition_free_list(network
->conditions
);
539 free(network
->description
);
540 free(network
->dhcp_vendor_class_identifier
);
541 strv_free(network
->dhcp_user_class
);
542 free(network
->dhcp_hostname
);
543 set_free(network
->dhcp_black_listed_ip
);
546 strv_free(network
->ntp
);
548 ordered_set_free_free(network
->search_domains
);
549 ordered_set_free_free(network
->route_domains
);
550 strv_free(network
->bind_carrier
);
552 ordered_set_free_free(network
->router_search_domains
);
553 free(network
->router_dns
);
554 set_free_free(network
->ndisc_black_listed_prefix
);
556 free(network
->bridge_name
);
557 free(network
->bond_name
);
558 free(network
->vrf_name
);
559 hashmap_free_free_key(network
->stacked_netdev_names
);
560 netdev_unref(network
->bridge
);
561 netdev_unref(network
->bond
);
562 netdev_unref(network
->vrf
);
563 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
565 while ((route
= network
->static_routes
))
568 while ((address
= network
->static_addresses
))
569 address_free(address
);
571 while ((fdb_entry
= network
->static_fdb_entries
))
572 fdb_entry_free(fdb_entry
);
574 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
575 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
577 while ((neighbor
= network
->neighbors
))
578 neighbor_free(neighbor
);
580 while ((label
= network
->address_labels
))
581 address_label_free(label
);
583 while ((prefix
= network
->static_prefixes
))
586 while ((rule
= network
->rules
))
587 routing_policy_rule_free(rule
);
589 hashmap_free(network
->addresses_by_section
);
590 hashmap_free(network
->routes_by_section
);
591 hashmap_free(network
->fdb_entries_by_section
);
592 hashmap_free(network
->neighbors_by_section
);
593 hashmap_free(network
->address_labels_by_section
);
594 hashmap_free(network
->prefixes_by_section
);
595 hashmap_free(network
->rules_by_section
);
597 if (network
->manager
) {
598 if (network
->manager
->networks
&& network
->name
)
599 ordered_hashmap_remove(network
->manager
->networks
, network
->name
);
601 if (network
->manager
->duids_requesting_uuid
)
602 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
607 free(network
->dhcp_server_timezone
);
608 free(network
->dhcp_server_dns
);
609 free(network
->dhcp_server_ntp
);
611 set_free_free(network
->dnssec_negative_trust_anchors
);
613 return mfree(network
);
616 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
618 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
625 network
= ordered_hashmap_get(manager
->networks
, name
);
634 int network_get(Manager
*manager
, sd_device
*device
,
635 const char *ifname
, const struct ether_addr
*address
,
643 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
644 if (net_match_config(network
->match_mac
, network
->match_path
, network
->match_driver
,
645 network
->match_type
, network
->match_name
, network
->match_property
,
646 device
, address
, ifname
)) {
647 if (network
->match_name
&& device
) {
649 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
651 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
652 (void) safe_atou8(attr
, &name_assign_type
);
654 if (name_assign_type
== NET_NAME_ENUM
)
655 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
656 ifname
, network
->filename
);
658 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
660 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
671 int network_apply(Network
*network
, Link
*link
) {
675 link
->network
= network_ref(network
);
677 if (network
->n_dns
> 0 ||
678 !strv_isempty(network
->ntp
) ||
679 !ordered_set_isempty(network
->search_domains
) ||
680 !ordered_set_isempty(network
->route_domains
))
686 bool network_has_static_ipv6_configurations(Network
*network
) {
694 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
695 if (address
->family
== AF_INET6
)
698 LIST_FOREACH(routes
, route
, network
->static_routes
)
699 if (route
->family
== AF_INET6
)
702 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
703 if (fdb
->family
== AF_INET6
)
706 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
707 if (neighbor
->family
== AF_INET6
)
710 if (!LIST_IS_EMPTY(network
->address_labels
))
713 if (!LIST_IS_EMPTY(network
->static_prefixes
))
719 int config_parse_stacked_netdev(const char *unit
,
720 const char *filename
,
723 unsigned section_line
,
729 _cleanup_free_
char *name
= NULL
;
730 NetDevKind kind
= ltype
;
739 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
740 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
741 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
744 if (!ifname_valid(rvalue
)) {
745 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
746 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
750 name
= strdup(rvalue
);
754 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
758 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
760 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
761 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
763 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
764 "NetDev '%s' specified twice, ignoring.", name
);
771 int config_parse_domains(
773 const char *filename
,
776 unsigned section_line
,
791 if (isempty(rvalue
)) {
792 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
793 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
799 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
803 r
= extract_first_word(&p
, &w
, NULL
, 0);
805 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
806 "Failed to extract search or route domain, ignoring: %s", rvalue
);
812 is_route
= w
[0] == '~';
813 domain
= is_route
? w
+ 1 : w
;
815 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
816 /* If the root domain appears as is, or the special token "*" is found, we'll
817 * consider this as routing domain, unconditionally. */
819 domain
= "."; /* make sure we don't allow empty strings, thus write the root
822 r
= dns_name_normalize(domain
, 0, &normalized
);
824 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
825 "'%s' is not a valid domain name, ignoring.", domain
);
831 if (is_localhost(domain
)) {
832 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
833 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
839 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
840 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
844 r
= ordered_set_put_strdup(*set
, domain
);
852 int config_parse_ipv6token(
854 const char *filename
,
857 unsigned section_line
,
864 union in_addr_union buffer
;
865 struct in6_addr
*token
= data
;
873 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
875 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
876 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
880 if (in_addr_is_null(AF_INET6
, &buffer
)) {
881 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
882 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
886 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
887 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
888 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
897 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
898 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
899 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
900 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
903 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
904 IPV6_PRIVACY_EXTENSIONS_YES
);
906 int config_parse_ipv6_privacy_extensions(
908 const char *filename
,
911 unsigned section_line
,
918 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
923 assert(ipv6_privacy_extensions
);
925 s
= ipv6_privacy_extensions_from_string(rvalue
);
927 if (streq(rvalue
, "kernel"))
928 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
930 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
931 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
936 *ipv6_privacy_extensions
= s
;
941 int config_parse_hostname(
943 const char *filename
,
946 unsigned section_line
,
953 _cleanup_free_
char *hn
= NULL
;
954 char **hostname
= data
;
961 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
965 if (!hostname_is_valid(hn
, false)) {
966 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
967 "Hostname is not valid, ignoring assignment: %s", rvalue
);
971 r
= dns_name_is_valid(hn
);
973 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
974 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
978 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
979 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
983 return free_and_replace(*hostname
, hn
);
986 int config_parse_timezone(
988 const char *filename
,
991 unsigned section_line
,
998 _cleanup_free_
char *tz
= NULL
;
1006 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1010 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1011 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1012 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1016 return free_and_replace(*datap
, tz
);
1019 int config_parse_dns(
1021 const char *filename
,
1023 const char *section
,
1024 unsigned section_line
,
1031 Network
*n
= userdata
;
1039 _cleanup_free_
char *w
= NULL
;
1040 union in_addr_union a
;
1041 struct in_addr_data
*m
;
1044 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1048 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1049 "Invalid syntax, ignoring: %s", rvalue
);
1055 r
= in_addr_from_string_auto(w
, &family
, &a
);
1057 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1058 "Failed to parse dns server address, ignoring: %s", w
);
1062 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1066 m
[n
->n_dns
++] = (struct in_addr_data
) {
1077 int config_parse_dnssec_negative_trust_anchors(
1079 const char *filename
,
1081 const char *section
,
1082 unsigned section_line
,
1089 const char *p
= rvalue
;
1097 if (isempty(rvalue
)) {
1098 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1103 _cleanup_free_
char *w
= NULL
;
1105 r
= extract_first_word(&p
, &w
, NULL
, 0);
1107 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1108 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1114 r
= dns_name_is_valid(w
);
1116 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1117 "%s is not a valid domain name, ignoring.", w
);
1121 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1125 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1135 int config_parse_ntp(
1137 const char *filename
,
1139 const char *section
,
1140 unsigned section_line
,
1154 if (isempty(rvalue
)) {
1160 _cleanup_free_
char *w
= NULL
;
1162 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1166 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1167 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1173 r
= dns_name_is_valid_or_address(w
);
1175 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1176 "%s is not a valid domain name or IP address, ignoring.", w
);
1180 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1181 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1182 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1183 MAX_NTP_SERVERS
, w
);
1187 r
= strv_consume(l
, TAKE_PTR(w
));
1195 int config_parse_required_for_online(
1197 const char *filename
,
1199 const char *section
,
1200 unsigned section_line
,
1207 Network
*network
= data
;
1208 LinkOperationalState s
;
1209 bool required
= true;
1212 if (isempty(rvalue
)) {
1213 network
->required_for_online
= true;
1214 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1218 s
= link_operstate_from_string(rvalue
);
1220 r
= parse_boolean(rvalue
);
1222 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1223 "Failed to parse %s= setting, ignoring assignment: %s",
1229 s
= LINK_OPERSTATE_DEGRADED
;
1232 network
->required_for_online
= required
;
1233 network
->required_operstate_for_online
= s
;
1238 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1239 "Failed to parse KeepConfiguration= setting");
1241 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1242 [KEEP_CONFIGURATION_NO
] = "no",
1243 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1244 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1245 [KEEP_CONFIGURATION_STATIC
] = "static",
1246 [KEEP_CONFIGURATION_YES
] = "yes",
1249 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);