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 static uint32_t network_get_stacked_netdevs_mtu(Network
*network
) {
151 HASHMAP_FOREACH(dev
, network
->stacked_netdevs
, i
)
152 if (dev
->kind
== NETDEV_KIND_VLAN
&& dev
->mtu
> 0)
153 /* See vlan_dev_change_mtu() in kernel.
154 * Note that the additional 4bytes may not be necessary for all devices. */
155 mtu
= MAX(mtu
, dev
->mtu
+ 4);
157 else if (dev
->kind
== NETDEV_KIND_MACVLAN
&& dev
->mtu
> mtu
)
158 /* See macvlan_change_mtu() in kernel. */
164 int network_verify(Network
*network
) {
165 Address
*address
, *address_next
;
166 Route
*route
, *route_next
;
167 FdbEntry
*fdb
, *fdb_next
;
168 Neighbor
*neighbor
, *neighbor_next
;
169 AddressLabel
*label
, *label_next
;
170 Prefix
*prefix
, *prefix_next
;
171 RoutingPolicyRule
*rule
, *rule_next
;
175 assert(network
->filename
);
177 if (set_isempty(network
->match_mac
) && strv_isempty(network
->match_path
) &&
178 strv_isempty(network
->match_driver
) && strv_isempty(network
->match_type
) &&
179 strv_isempty(network
->match_name
) && !network
->conditions
)
180 log_warning("%s: No valid settings found in the [Match] section. "
181 "The file will match all interfaces. "
182 "If that is intended, please add Name=* in the [Match] section.",
185 /* skip out early if configuration does not match the environment */
186 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
187 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
188 "%s: Conditions in the file do not match the system environment, skipping.",
191 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
192 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
193 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
194 (void) network_resolve_stacked_netdevs(network
);
196 /* Free unnecessary entries. */
197 network
->bond_name
= mfree(network
->bond_name
);
198 network
->bridge_name
= mfree(network
->bridge_name
);
199 network
->vrf_name
= mfree(network
->vrf_name
);
200 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
203 /* Bonding slave does not support addressing. */
204 if (network
->ipv6_accept_ra
> 0) {
205 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
207 network
->ipv6_accept_ra
= 0;
209 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
210 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
212 network
->link_local
= ADDRESS_FAMILY_NO
;
214 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
215 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
217 network
->dhcp
= ADDRESS_FAMILY_NO
;
219 if (network
->dhcp_server
) {
220 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
222 network
->dhcp_server
= false;
224 if (network
->n_static_addresses
> 0) {
225 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
227 while ((address
= network
->static_addresses
))
228 address_free(address
);
230 if (network
->n_static_routes
> 0) {
231 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
233 while ((route
= network
->static_routes
))
238 if (network
->link_local
< 0)
239 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
241 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
242 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
243 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
244 "Disabling the fallback assignment.", network
->filename
);
245 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
248 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
249 network
->ipv6_accept_ra
= false;
251 /* IPMasquerade=yes implies IPForward=yes */
252 if (network
->ip_masquerade
)
253 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
255 network
->mtu_is_set
= network
->mtu
> 0;
256 mtu
= network_get_stacked_netdevs_mtu(network
);
257 if (network
->mtu
< mtu
) {
258 if (network
->mtu_is_set
)
259 log_notice("%s: Bumping MTUBytes= from %"PRIu32
" to %"PRIu32
" because of stacked device",
260 network
->filename
, network
->mtu
, mtu
);
264 if (network
->mtu_is_set
&& network
->dhcp_use_mtu
) {
265 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
266 "Disabling UseMTU=.", network
->filename
);
267 network
->dhcp_use_mtu
= false;
270 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
271 if (address_section_verify(address
) < 0)
272 address_free(address
);
274 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
275 if (route_section_verify(route
, network
) < 0)
278 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
279 if (section_is_invalid(fdb
->section
))
282 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
283 if (section_is_invalid(neighbor
->section
))
284 neighbor_free(neighbor
);
286 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
287 if (section_is_invalid(label
->section
))
288 address_label_free(label
);
290 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
291 if (section_is_invalid(prefix
->section
))
294 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
295 if (section_is_invalid(rule
->section
))
296 routing_policy_rule_free(rule
);
301 int network_load_one(Manager
*manager
, const char *filename
) {
302 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
303 _cleanup_(network_unrefp
) Network
*network
= NULL
;
304 _cleanup_fclose_
FILE *file
= NULL
;
305 const char *dropin_dirname
;
312 file
= fopen(filename
, "re");
320 if (null_or_empty_fd(fileno(file
))) {
321 log_debug("Skipping empty file: %s", filename
);
325 fname
= strdup(filename
);
329 name
= strdup(basename(filename
));
333 d
= strrchr(name
, '.');
339 dropin_dirname
= strjoina(name
, ".network.d");
341 network
= new(Network
, 1);
345 *network
= (Network
) {
346 .filename
= TAKE_PTR(fname
),
347 .name
= TAKE_PTR(name
),
352 .required_for_online
= true,
353 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
354 .dhcp
= ADDRESS_FAMILY_NO
,
355 .dhcp_use_ntp
= true,
356 .dhcp_use_dns
= true,
357 .dhcp_use_hostname
= true,
358 .dhcp_use_routes
= true,
359 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
360 .dhcp_send_hostname
= true,
361 /* To enable/disable RFC7844 Anonymity Profiles */
362 .dhcp_anonymize
= false,
363 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
364 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
365 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
366 .dhcp_route_table
= RT_TABLE_MAIN
,
367 .dhcp_route_table_set
= false,
368 /* NOTE: from man: UseMTU=... Defaults to false*/
369 .dhcp_use_mtu
= false,
370 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
371 .dhcp_use_timezone
= false,
372 .rapid_commit
= true,
374 .dhcp_server_emit_dns
= true,
375 .dhcp_server_emit_ntp
= true,
376 .dhcp_server_emit_router
= true,
377 .dhcp_server_emit_timezone
= true,
379 .router_emit_dns
= true,
380 .router_emit_domains
= true,
385 .allow_port_to_be_root
= -1,
387 .multicast_flood
= -1,
388 .multicast_to_unicast
= -1,
389 .neighbor_suppression
= -1,
391 .bridge_proxy_arp
= -1,
392 .bridge_proxy_arp_wifi
= -1,
393 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
395 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
397 .dns_default_route
= -1,
398 .llmnr
= RESOLVE_SUPPORT_YES
,
399 .mdns
= RESOLVE_SUPPORT_NO
,
400 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
401 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
403 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
404 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
406 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
407 .ipv6_accept_ra
= -1,
408 .ipv6_dad_transmits
= -1,
409 .ipv6_hop_limit
= -1,
410 .ipv6_proxy_ndp
= -1,
411 .duid
.type
= _DUID_TYPE_INVALID
,
416 .ipv6_accept_ra_use_dns
= true,
417 .ipv6_accept_ra_use_autonomous_prefix
= true,
418 .ipv6_accept_ra_use_onlink_prefix
= true,
419 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
420 .ipv6_accept_ra_route_table_set
= false,
422 .can_triple_sampling
= -1,
425 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
432 "RoutingPolicyRule\0"
435 "DHCPv4\0" /* compat */
438 "IPv6NDPProxyAddress\0"
442 "IPv6PrefixDelegation\0"
445 config_item_perf_lookup
, network_network_gperf_lookup
,
446 CONFIG_PARSE_WARN
, network
);
450 network_apply_anonymize_if_set(network
);
452 r
= network_add_ipv4ll_route(network
);
454 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
456 r
= ordered_hashmap_ensure_allocated(&manager
->networks
, &string_hash_ops
);
460 r
= ordered_hashmap_put(manager
->networks
, network
->name
, network
);
464 if (network_verify(network
) < 0)
471 int network_load(Manager
*manager
) {
472 _cleanup_strv_free_
char **files
= NULL
;
478 ordered_hashmap_clear_with_destructor(manager
->networks
, network_unref
);
480 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
482 return log_error_errno(r
, "Failed to enumerate network files: %m");
484 STRV_FOREACH(f
, files
) {
485 r
= network_load_one(manager
, *f
);
493 static Network
*network_free(Network
*network
) {
494 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
495 RoutingPolicyRule
*rule
;
506 free(network
->filename
);
508 set_free_free(network
->match_mac
);
509 strv_free(network
->match_path
);
510 strv_free(network
->match_driver
);
511 strv_free(network
->match_type
);
512 strv_free(network
->match_name
);
513 condition_free_list(network
->conditions
);
515 free(network
->description
);
516 free(network
->dhcp_vendor_class_identifier
);
517 strv_free(network
->dhcp_user_class
);
518 free(network
->dhcp_hostname
);
522 strv_free(network
->ntp
);
524 ordered_set_free_free(network
->search_domains
);
525 ordered_set_free_free(network
->route_domains
);
526 strv_free(network
->bind_carrier
);
528 ordered_set_free_free(network
->router_search_domains
);
529 free(network
->router_dns
);
531 free(network
->bridge_name
);
532 free(network
->bond_name
);
533 free(network
->vrf_name
);
534 hashmap_free_free_key(network
->stacked_netdev_names
);
535 netdev_unref(network
->bridge
);
536 netdev_unref(network
->bond
);
537 netdev_unref(network
->vrf
);
538 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
540 while ((route
= network
->static_routes
))
543 while ((address
= network
->static_addresses
))
544 address_free(address
);
546 while ((fdb_entry
= network
->static_fdb_entries
))
547 fdb_entry_free(fdb_entry
);
549 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
550 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
552 while ((neighbor
= network
->neighbors
))
553 neighbor_free(neighbor
);
555 while ((label
= network
->address_labels
))
556 address_label_free(label
);
558 while ((prefix
= network
->static_prefixes
))
561 while ((rule
= network
->rules
))
562 routing_policy_rule_free(rule
);
564 hashmap_free(network
->addresses_by_section
);
565 hashmap_free(network
->routes_by_section
);
566 hashmap_free(network
->fdb_entries_by_section
);
567 hashmap_free(network
->neighbors_by_section
);
568 hashmap_free(network
->address_labels_by_section
);
569 hashmap_free(network
->prefixes_by_section
);
570 hashmap_free(network
->rules_by_section
);
572 if (network
->manager
) {
573 if (network
->manager
->networks
&& network
->name
)
574 ordered_hashmap_remove(network
->manager
->networks
, network
->name
);
576 if (network
->manager
->duids_requesting_uuid
)
577 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
582 free(network
->dhcp_server_timezone
);
583 free(network
->dhcp_server_dns
);
584 free(network
->dhcp_server_ntp
);
586 set_free_free(network
->dnssec_negative_trust_anchors
);
588 return mfree(network
);
591 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
593 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
600 network
= ordered_hashmap_get(manager
->networks
, name
);
609 int network_get(Manager
*manager
, sd_device
*device
,
610 const char *ifname
, const struct ether_addr
*address
,
612 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
620 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
622 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
624 (void) sd_device_get_devtype(device
, &devtype
);
627 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
628 if (net_match_config(network
->match_mac
, network
->match_path
,
629 network
->match_driver
, network
->match_type
,
631 address
, path
, driver
, devtype
, ifname
)) {
632 if (network
->match_name
&& device
) {
634 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
636 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
637 (void) safe_atou8(attr
, &name_assign_type
);
639 if (name_assign_type
== NET_NAME_ENUM
)
640 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
641 ifname
, network
->filename
);
643 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
645 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
656 int network_apply(Network
*network
, Link
*link
) {
660 link
->network
= network_ref(network
);
662 if (network
->n_dns
> 0 ||
663 !strv_isempty(network
->ntp
) ||
664 !ordered_set_isempty(network
->search_domains
) ||
665 !ordered_set_isempty(network
->route_domains
))
671 bool network_has_static_ipv6_addresses(Network
*network
) {
676 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
677 if (address
->family
== AF_INET6
)
684 int config_parse_stacked_netdev(const char *unit
,
685 const char *filename
,
688 unsigned section_line
,
694 _cleanup_free_
char *name
= NULL
;
695 NetDevKind kind
= ltype
;
704 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
705 NETDEV_KIND_IPVLAN
, NETDEV_KIND_VXLAN
, NETDEV_KIND_L2TP
,
706 NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
));
708 if (!ifname_valid(rvalue
)) {
709 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
710 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
714 name
= strdup(rvalue
);
718 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
722 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
724 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
725 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
727 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
728 "NetDev '%s' specified twice, ignoring.", name
);
735 int config_parse_domains(
737 const char *filename
,
740 unsigned section_line
,
755 if (isempty(rvalue
)) {
756 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
757 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
763 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
767 r
= extract_first_word(&p
, &w
, NULL
, 0);
769 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
770 "Failed to extract search or route domain, ignoring: %s", rvalue
);
776 is_route
= w
[0] == '~';
777 domain
= is_route
? w
+ 1 : w
;
779 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
780 /* If the root domain appears as is, or the special token "*" is found, we'll
781 * consider this as routing domain, unconditionally. */
783 domain
= "."; /* make sure we don't allow empty strings, thus write the root
786 r
= dns_name_normalize(domain
, 0, &normalized
);
788 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
789 "'%s' is not a valid domain name, ignoring.", domain
);
795 if (is_localhost(domain
)) {
796 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
797 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
803 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
804 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
808 r
= ordered_set_put_strdup(*set
, domain
);
816 int config_parse_ipv4ll(
818 const char *filename
,
821 unsigned section_line
,
828 AddressFamilyBoolean
*link_local
= data
;
836 /* Note that this is mostly like
837 * config_parse_address_family_boolean(), except that it
838 * applies only to IPv4 */
840 r
= parse_boolean(rvalue
);
842 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
843 "Failed to parse %s=%s, ignoring assignment. "
844 "Note that the setting %s= is deprecated, please use LinkLocalAddressing= instead.",
845 lvalue
, rvalue
, lvalue
);
849 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, r
);
851 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
852 "%s=%s is deprecated, please use LinkLocalAddressing=%s instead.",
853 lvalue
, rvalue
, address_family_boolean_to_string(*link_local
));
858 int config_parse_dhcp(
860 const char *filename
,
863 unsigned section_line
,
870 AddressFamilyBoolean
*dhcp
= data
, s
;
877 /* Note that this is mostly like
878 * config_parse_address_family_boolean(), except that it
879 * understands some old names for the enum values */
881 s
= address_family_boolean_from_string(rvalue
);
884 /* Previously, we had a slightly different enum here,
885 * support its values for compatibility. */
887 if (streq(rvalue
, "none"))
888 s
= ADDRESS_FAMILY_NO
;
889 else if (streq(rvalue
, "v4"))
890 s
= ADDRESS_FAMILY_IPV4
;
891 else if (streq(rvalue
, "v6"))
892 s
= ADDRESS_FAMILY_IPV6
;
893 else if (streq(rvalue
, "both"))
894 s
= ADDRESS_FAMILY_YES
;
896 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
897 "Failed to parse DHCP option, ignoring: %s", rvalue
);
901 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
902 "DHCP=%s is deprecated, please use DHCP=%s instead.",
903 rvalue
, address_family_boolean_to_string(s
));
910 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
911 [DHCP_CLIENT_ID_MAC
] = "mac",
912 [DHCP_CLIENT_ID_DUID
] = "duid",
913 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
916 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
917 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
918 "Failed to parse client identifier type");
920 int config_parse_ipv6token(
922 const char *filename
,
925 unsigned section_line
,
932 union in_addr_union buffer
;
933 struct in6_addr
*token
= data
;
941 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
943 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
944 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
948 if (in_addr_is_null(AF_INET6
, &buffer
)) {
949 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
950 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
954 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
955 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
956 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
965 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
966 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
967 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
968 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
971 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
973 int config_parse_ipv6_privacy_extensions(
975 const char *filename
,
978 unsigned section_line
,
985 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
991 assert(ipv6_privacy_extensions
);
993 /* Our enum shall be a superset of booleans, hence first try
994 * to parse as boolean, and then as enum */
996 k
= parse_boolean(rvalue
);
998 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
1000 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
1002 IPv6PrivacyExtensions s
;
1004 s
= ipv6_privacy_extensions_from_string(rvalue
);
1007 if (streq(rvalue
, "kernel"))
1008 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1010 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1011 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1016 *ipv6_privacy_extensions
= s
;
1022 int config_parse_hostname(
1024 const char *filename
,
1026 const char *section
,
1027 unsigned section_line
,
1034 _cleanup_free_
char *hn
= NULL
;
1035 char **hostname
= data
;
1042 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1046 if (!hostname_is_valid(hn
, false)) {
1047 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1048 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1052 r
= dns_name_is_valid(hn
);
1054 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1055 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1059 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1060 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1064 return free_and_replace(*hostname
, hn
);
1067 int config_parse_timezone(
1069 const char *filename
,
1071 const char *section
,
1072 unsigned section_line
,
1079 _cleanup_free_
char *tz
= NULL
;
1080 char **datap
= data
;
1087 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1091 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1092 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1093 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1097 return free_and_replace(*datap
, tz
);
1100 int config_parse_dhcp_server_dns(
1102 const char *filename
,
1104 const char *section
,
1105 unsigned section_line
,
1113 const char *p
= rvalue
;
1121 _cleanup_free_
char *w
= NULL
;
1122 union in_addr_union a
;
1125 r
= extract_first_word(&p
, &w
, NULL
, 0);
1129 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1130 "Failed to extract word, ignoring: %s", rvalue
);
1136 r
= in_addr_from_string(AF_INET
, w
, &a
);
1138 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1139 "Failed to parse DNS server address '%s', ignoring assignment: %m", w
);
1143 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1147 m
[n
->n_dhcp_server_dns
++] = a
.in
;
1148 n
->dhcp_server_dns
= m
;
1154 int config_parse_radv_dns(
1156 const char *filename
,
1158 const char *section
,
1159 unsigned section_line
,
1167 const char *p
= rvalue
;
1175 _cleanup_free_
char *w
= NULL
;
1176 union in_addr_union a
;
1178 r
= extract_first_word(&p
, &w
, NULL
, 0);
1182 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1183 "Failed to extract word, ignoring: %s", rvalue
);
1189 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1192 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1196 m
[n
->n_router_dns
++] = a
.in6
;
1200 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1201 "Failed to parse DNS server address, ignoring: %s", w
);
1207 int config_parse_radv_search_domains(
1209 const char *filename
,
1211 const char *section
,
1212 unsigned section_line
,
1220 const char *p
= rvalue
;
1228 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1230 r
= extract_first_word(&p
, &w
, NULL
, 0);
1234 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1235 "Failed to extract word, ignoring: %s", rvalue
);
1241 r
= dns_name_apply_idna(w
, &idna
);
1243 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1244 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1247 /* transfer ownership to simplify subsequent operations */
1250 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1254 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1262 int config_parse_dhcp_server_ntp(
1264 const char *filename
,
1266 const char *section
,
1267 unsigned section_line
,
1275 const char *p
= rvalue
;
1283 _cleanup_free_
char *w
= NULL
;
1284 union in_addr_union a
;
1287 r
= extract_first_word(&p
, &w
, NULL
, 0);
1291 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1292 "Failed to extract word, ignoring: %s", rvalue
);
1298 r
= in_addr_from_string(AF_INET
, w
, &a
);
1300 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1301 "Failed to parse NTP server address '%s', ignoring: %m", w
);
1305 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1309 m
[n
->n_dhcp_server_ntp
++] = a
.in
;
1310 n
->dhcp_server_ntp
= m
;
1314 int config_parse_dns(
1316 const char *filename
,
1318 const char *section
,
1319 unsigned section_line
,
1326 Network
*n
= userdata
;
1334 _cleanup_free_
char *w
= NULL
;
1335 union in_addr_union a
;
1336 struct in_addr_data
*m
;
1339 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1343 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1344 "Invalid syntax, ignoring: %s", rvalue
);
1350 r
= in_addr_from_string_auto(w
, &family
, &a
);
1352 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1353 "Failed to parse dns server address, ignoring: %s", w
);
1357 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1361 m
[n
->n_dns
++] = (struct in_addr_data
) {
1372 int config_parse_dnssec_negative_trust_anchors(
1374 const char *filename
,
1376 const char *section
,
1377 unsigned section_line
,
1384 const char *p
= rvalue
;
1392 if (isempty(rvalue
)) {
1393 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1398 _cleanup_free_
char *w
= NULL
;
1400 r
= extract_first_word(&p
, &w
, NULL
, 0);
1402 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1403 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1409 r
= dns_name_is_valid(w
);
1411 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1412 "%s is not a valid domain name, ignoring.", w
);
1416 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1420 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1430 int config_parse_ntp(
1432 const char *filename
,
1434 const char *section
,
1435 unsigned section_line
,
1449 if (isempty(rvalue
)) {
1455 _cleanup_free_
char *w
= NULL
;
1457 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1461 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1462 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1468 r
= dns_name_is_valid_or_address(w
);
1470 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1471 "%s is not a valid domain name or IP address, ignoring.", w
);
1475 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1476 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1477 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1478 MAX_NTP_SERVERS
, w
);
1482 r
= strv_consume(l
, TAKE_PTR(w
));
1490 int config_parse_dhcp_user_class(
1492 const char *filename
,
1494 const char *section
,
1495 unsigned section_line
,
1509 if (isempty(rvalue
)) {
1515 _cleanup_free_
char *w
= NULL
;
1517 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1521 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1522 "Failed to split user classes option, ignoring: %s", rvalue
);
1528 if (strlen(w
) > 255) {
1529 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1530 "%s length is not in the range 1-255, ignoring.", w
);
1534 r
= strv_push(l
, w
);
1544 int config_parse_section_route_table(
1546 const char *filename
,
1548 const char *section
,
1549 unsigned section_line
,
1556 Network
*network
= data
;
1565 r
= safe_atou32(rvalue
, &rt
);
1567 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1568 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1572 if (streq_ptr(section
, "DHCP")) {
1573 network
->dhcp_route_table
= rt
;
1574 network
->dhcp_route_table_set
= true;
1575 } else { /* section is IPv6AcceptRA */
1576 network
->ipv6_accept_ra_route_table
= rt
;
1577 network
->ipv6_accept_ra_route_table_set
= true;
1583 int config_parse_dhcp_max_attempts(
1585 const char *filename
,
1587 const char *section
,
1588 unsigned section_line
,
1595 Network
*network
= data
;
1603 if (isempty(rvalue
)) {
1604 network
->dhcp_max_attempts
= 0;
1608 if (streq(rvalue
, "infinity")) {
1609 network
->dhcp_max_attempts
= (uint64_t) -1;
1613 r
= safe_atou64(rvalue
, &a
);
1615 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1616 "Failed to parse DHCP maximum attempts, ignoring: %s", rvalue
);
1621 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1622 "%s= must be positive integer or 'infinity', ignoring: %s", lvalue
, rvalue
);
1626 network
->dhcp_max_attempts
= a
;
1631 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1632 "Failed to parse DHCP use domains setting");
1634 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1635 [DHCP_USE_DOMAINS_NO
] = "no",
1636 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1637 [DHCP_USE_DOMAINS_YES
] = "yes",
1640 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1642 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1644 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1645 [LLDP_MODE_NO
] = "no",
1646 [LLDP_MODE_YES
] = "yes",
1647 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1650 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
1652 int config_parse_iaid(const char *unit
,
1653 const char *filename
,
1655 const char *section
,
1656 unsigned section_line
,
1662 Network
*network
= data
;
1671 r
= safe_atou32(rvalue
, &iaid
);
1673 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1674 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1678 network
->iaid
= iaid
;
1679 network
->iaid_set
= true;
1684 int config_parse_required_for_online(
1686 const char *filename
,
1688 const char *section
,
1689 unsigned section_line
,
1696 Network
*network
= data
;
1697 LinkOperationalState s
;
1698 bool required
= true;
1701 if (isempty(rvalue
)) {
1702 network
->required_for_online
= true;
1703 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1707 s
= link_operstate_from_string(rvalue
);
1709 r
= parse_boolean(rvalue
);
1711 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1712 "Failed to parse %s= setting, ignoring assignment: %s",
1718 s
= LINK_OPERSTATE_DEGRADED
;
1721 network
->required_for_online
= required
;
1722 network
->required_operstate_for_online
= s
;