1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include <linux/netdevice.h>
5 #include "alloc-util.h"
6 #include "conf-files.h"
7 #include "conf-parser.h"
8 #include "dns-domain.h"
10 #include "hostname-util.h"
11 #include "in-addr-util.h"
12 #include "network-internal.h"
13 #include "networkd-manager.h"
14 #include "networkd-network.h"
15 #include "parse-util.h"
17 #include "socket-util.h"
18 #include "stat-util.h"
19 #include "string-table.h"
20 #include "string-util.h"
24 /* Let's assume that anything above this number is a user misconfiguration. */
25 #define MAX_NTP_SERVERS 128
27 /* Set defaults following RFC7844 */
28 void network_apply_anonymize_if_set(Network
*network
) {
29 if (!network
->dhcp_anonymize
)
32 SHOULD NOT send the Host Name option */
33 network
->dhcp_send_hostname
= false;
34 /* RFC7844 section 3.:
35 MAY contain the Client Identifier option
37 clients MUST use client identifiers based solely
38 on the link-layer address */
39 /* NOTE: Using MAC, as it does not reveal extra information,
40 * and some servers might not answer if this option is not sent */
41 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
43 SHOULD NOT use the Vendor Class Identifier option */
44 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
45 /* RFC7844 section 3.6.:
46 The client intending to protect its privacy SHOULD only request a
47 minimal number of options in the PRL and SHOULD also randomly shuffle
48 the ordering of option codes in the PRL. If this random ordering
49 cannot be implemented, the client MAY order the option codes in the
50 PRL by option code number (lowest to highest).
52 /* NOTE: dhcp_use_mtu is false by default,
53 * though it was not initiallized to any value in network_load_one.
54 * Maybe there should be another var called *send*?
55 * (to use the MTU sent by the server but to do not send
56 * the option in the PRL). */
57 network
->dhcp_use_mtu
= false;
58 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
59 * but this is needed to use them. */
60 network
->dhcp_use_routes
= true;
61 /* RFC7844 section 3.6.
62 * same comments as previous option */
63 network
->dhcp_use_timezone
= false;
66 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
67 const char *kind_string
;
71 /* For test-networkd-conf, the check must be earlier than the assertions. */
76 assert(network
->manager
);
77 assert(network
->filename
);
80 if (kind
== _NETDEV_KIND_TUNNEL
)
81 kind_string
= "tunnel";
83 kind_string
= netdev_kind_to_string(kind
);
85 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
86 "%s: Invalid NetDev kind of %s, ignoring assignment.",
87 network
->filename
, name
);
90 r
= netdev_get(network
->manager
, name
, &netdev
);
92 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
93 network
->filename
, name
);
95 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
102 NETDEV_KIND_IP6GRETAP
,
106 NETDEV_KIND_ERSPAN
)))
107 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
108 "%s: NetDev %s is not a %s, ignoring assignment",
109 network
->filename
, name
, kind_string
);
111 *ret_netdev
= netdev_ref(netdev
);
115 static int network_resolve_stacked_netdevs(Network
*network
) {
122 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
123 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
125 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
129 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
133 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
135 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
136 network
->filename
, (const char *) name
);
144 static uint32_t network_get_stacked_netdevs_mtu(Network
*network
) {
149 HASHMAP_FOREACH(dev
, network
->stacked_netdevs
, i
)
150 if (dev
->kind
== NETDEV_KIND_VLAN
&& dev
->mtu
> 0)
151 /* See vlan_dev_change_mtu() in kernel.
152 * Note that the additional 4bytes may not be necessary for all devices. */
153 mtu
= MAX(mtu
, dev
->mtu
+ 4);
155 else if (dev
->kind
== NETDEV_KIND_MACVLAN
&& dev
->mtu
> mtu
)
156 /* See macvlan_change_mtu() in kernel. */
162 int network_verify(Network
*network
) {
163 Address
*address
, *address_next
;
164 Route
*route
, *route_next
;
165 FdbEntry
*fdb
, *fdb_next
;
166 Neighbor
*neighbor
, *neighbor_next
;
167 AddressLabel
*label
, *label_next
;
168 Prefix
*prefix
, *prefix_next
;
169 RoutingPolicyRule
*rule
, *rule_next
;
173 assert(network
->filename
);
175 if (set_isempty(network
->match_mac
) && strv_isempty(network
->match_path
) &&
176 strv_isempty(network
->match_driver
) && strv_isempty(network
->match_type
) &&
177 strv_isempty(network
->match_name
) && !network
->conditions
)
178 log_warning("%s: No valid settings found in the [Match] section. "
179 "The file will match all interfaces. "
180 "If that is intended, please add Name=* in the [Match] section.",
183 /* skip out early if configuration does not match the environment */
184 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
185 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
186 "%s: Conditions in the file do not match the system environment, skipping.",
189 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
190 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
191 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
192 (void) network_resolve_stacked_netdevs(network
);
194 /* Free unnecessary entries. */
195 network
->bond_name
= mfree(network
->bond_name
);
196 network
->bridge_name
= mfree(network
->bridge_name
);
197 network
->vrf_name
= mfree(network
->vrf_name
);
198 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
201 /* Bonding slave does not support addressing. */
202 if (network
->ipv6_accept_ra
> 0) {
203 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
205 network
->ipv6_accept_ra
= 0;
207 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
208 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
210 network
->link_local
= ADDRESS_FAMILY_NO
;
212 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
213 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
215 network
->dhcp
= ADDRESS_FAMILY_NO
;
217 if (network
->dhcp_server
) {
218 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
220 network
->dhcp_server
= false;
222 if (network
->n_static_addresses
> 0) {
223 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
225 while ((address
= network
->static_addresses
))
226 address_free(address
);
228 if (network
->n_static_routes
> 0) {
229 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
231 while ((route
= network
->static_routes
))
236 if (network
->link_local
< 0)
237 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
239 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
240 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
241 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
242 "Disabling the fallback assignment.", network
->filename
);
243 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
246 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
247 network
->ipv6_accept_ra
= false;
249 /* IPMasquerade=yes implies IPForward=yes */
250 if (network
->ip_masquerade
)
251 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
253 network
->mtu_is_set
= network
->mtu
> 0;
254 mtu
= network_get_stacked_netdevs_mtu(network
);
255 if (network
->mtu
< mtu
) {
256 if (network
->mtu_is_set
)
257 log_notice("%s: Bumping MTUBytes= from %"PRIu32
" to %"PRIu32
" because of stacked device",
258 network
->filename
, network
->mtu
, mtu
);
262 if (network
->mtu_is_set
&& network
->dhcp_use_mtu
) {
263 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
264 "Disabling UseMTU=.", network
->filename
);
265 network
->dhcp_use_mtu
= false;
268 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
269 if (address_section_verify(address
) < 0)
270 address_free(address
);
272 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
273 if (route_section_verify(route
, network
) < 0)
276 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
277 if (section_is_invalid(fdb
->section
))
280 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
281 if (section_is_invalid(neighbor
->section
))
282 neighbor_free(neighbor
);
284 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
285 if (section_is_invalid(label
->section
))
286 address_label_free(label
);
288 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
289 if (section_is_invalid(prefix
->section
))
292 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
293 if (section_is_invalid(rule
->section
))
294 routing_policy_rule_free(rule
);
299 int network_load_one(Manager
*manager
, const char *filename
) {
300 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
301 _cleanup_(network_freep
) Network
*network
= NULL
;
302 _cleanup_fclose_
FILE *file
= NULL
;
303 const char *dropin_dirname
;
310 file
= fopen(filename
, "re");
318 if (null_or_empty_fd(fileno(file
))) {
319 log_debug("Skipping empty file: %s", filename
);
323 fname
= strdup(filename
);
327 name
= strdup(basename(filename
));
331 d
= strrchr(name
, '.');
337 dropin_dirname
= strjoina(name
, ".network.d");
339 network
= new(Network
, 1);
343 *network
= (Network
) {
344 .filename
= TAKE_PTR(fname
),
345 .name
= TAKE_PTR(name
),
347 .required_for_online
= true,
348 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
349 .dhcp
= ADDRESS_FAMILY_NO
,
350 .dhcp_use_ntp
= true,
351 .dhcp_use_dns
= true,
352 .dhcp_use_hostname
= true,
353 .dhcp_use_routes
= true,
354 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
355 .dhcp_send_hostname
= true,
356 /* To enable/disable RFC7844 Anonymity Profiles */
357 .dhcp_anonymize
= false,
358 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
359 /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
360 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
361 .dhcp_route_table
= RT_TABLE_MAIN
,
362 .dhcp_route_table_set
= false,
363 /* NOTE: from man: UseMTU=... Defaults to false*/
364 .dhcp_use_mtu
= false,
365 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
366 .dhcp_use_timezone
= false,
367 .rapid_commit
= true,
369 .dhcp_server_emit_dns
= true,
370 .dhcp_server_emit_ntp
= true,
371 .dhcp_server_emit_router
= true,
372 .dhcp_server_emit_timezone
= true,
374 .router_emit_dns
= true,
375 .router_emit_domains
= true,
380 .allow_port_to_be_root
= -1,
382 .multicast_flood
= -1,
383 .multicast_to_unicast
= -1,
384 .neighbor_suppression
= -1,
386 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
388 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
390 .dns_default_route
= -1,
391 .llmnr
= RESOLVE_SUPPORT_YES
,
392 .mdns
= RESOLVE_SUPPORT_NO
,
393 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
394 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
396 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
397 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
399 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
400 .ipv6_accept_ra
= -1,
401 .ipv6_dad_transmits
= -1,
402 .ipv6_hop_limit
= -1,
403 .ipv6_proxy_ndp
= -1,
404 .duid
.type
= _DUID_TYPE_INVALID
,
409 .ipv6_accept_ra_use_dns
= true,
410 .ipv6_accept_ra_use_autonomous_prefix
= true,
411 .ipv6_accept_ra_use_onlink_prefix
= true,
412 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
413 .ipv6_accept_ra_route_table_set
= false,
415 .can_triple_sampling
= -1,
418 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
425 "RoutingPolicyRule\0"
428 "DHCPv4\0" /* compat */
431 "IPv6NDPProxyAddress\0"
435 "IPv6PrefixDelegation\0"
438 config_item_perf_lookup
, network_network_gperf_lookup
,
439 CONFIG_PARSE_WARN
, network
);
443 network_apply_anonymize_if_set(network
);
445 r
= network_add_ipv4ll_route(network
);
447 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
449 LIST_PREPEND(networks
, manager
->networks
, network
);
450 network
->manager
= manager
;
452 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
456 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
460 if (network_verify(network
) < 0)
467 int network_load(Manager
*manager
) {
469 _cleanup_strv_free_
char **files
= NULL
;
475 while ((network
= manager
->networks
))
476 network_free(network
);
478 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
480 return log_error_errno(r
, "Failed to enumerate network files: %m");
482 STRV_FOREACH_BACKWARDS(f
, files
) {
483 r
= network_load_one(manager
, *f
);
491 void network_free(Network
*network
) {
492 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
493 RoutingPolicyRule
*rule
;
504 free(network
->filename
);
506 set_free_free(network
->match_mac
);
507 strv_free(network
->match_path
);
508 strv_free(network
->match_driver
);
509 strv_free(network
->match_type
);
510 strv_free(network
->match_name
);
511 condition_free_list(network
->conditions
);
513 free(network
->description
);
514 free(network
->dhcp_vendor_class_identifier
);
515 strv_free(network
->dhcp_user_class
);
516 free(network
->dhcp_hostname
);
520 strv_free(network
->ntp
);
522 ordered_set_free_free(network
->search_domains
);
523 ordered_set_free_free(network
->route_domains
);
524 strv_free(network
->bind_carrier
);
526 ordered_set_free_free(network
->router_search_domains
);
527 free(network
->router_dns
);
529 free(network
->bridge_name
);
530 free(network
->bond_name
);
531 free(network
->vrf_name
);
532 hashmap_free_free_key(network
->stacked_netdev_names
);
533 netdev_unref(network
->bridge
);
534 netdev_unref(network
->bond
);
535 netdev_unref(network
->vrf
);
536 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
538 while ((route
= network
->static_routes
))
541 while ((address
= network
->static_addresses
))
542 address_free(address
);
544 while ((fdb_entry
= network
->static_fdb_entries
))
545 fdb_entry_free(fdb_entry
);
547 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
548 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
550 while ((neighbor
= network
->neighbors
))
551 neighbor_free(neighbor
);
553 while ((label
= network
->address_labels
))
554 address_label_free(label
);
556 while ((prefix
= network
->static_prefixes
))
559 while ((rule
= network
->rules
))
560 routing_policy_rule_free(rule
);
562 hashmap_free(network
->addresses_by_section
);
563 hashmap_free(network
->routes_by_section
);
564 hashmap_free(network
->fdb_entries_by_section
);
565 hashmap_free(network
->neighbors_by_section
);
566 hashmap_free(network
->address_labels_by_section
);
567 hashmap_free(network
->prefixes_by_section
);
568 hashmap_free(network
->rules_by_section
);
570 if (network
->manager
) {
571 if (network
->manager
->networks
)
572 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
574 if (network
->manager
->networks_by_name
&& network
->name
)
575 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
577 if (network
->manager
->duids_requesting_uuid
)
578 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
583 free(network
->dhcp_server_timezone
);
584 free(network
->dhcp_server_dns
);
585 free(network
->dhcp_server_ntp
);
587 set_free_free(network
->dnssec_negative_trust_anchors
);
592 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
599 network
= hashmap_get(manager
->networks_by_name
, name
);
608 int network_get(Manager
*manager
, sd_device
*device
,
609 const char *ifname
, const struct ether_addr
*address
,
611 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
618 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
620 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
622 (void) sd_device_get_devtype(device
, &devtype
);
625 LIST_FOREACH(networks
, network
, manager
->networks
) {
626 if (net_match_config(network
->match_mac
, network
->match_path
,
627 network
->match_driver
, network
->match_type
,
629 address
, path
, driver
, devtype
, ifname
)) {
630 if (network
->match_name
&& device
) {
632 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
634 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
635 (void) safe_atou8(attr
, &name_assign_type
);
637 if (name_assign_type
== NET_NAME_ENUM
)
638 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
639 ifname
, network
->filename
);
641 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
643 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
655 int network_apply(Network
*network
, Link
*link
) {
659 link
->network
= network
;
661 if (network
->n_dns
> 0 ||
662 !strv_isempty(network
->ntp
) ||
663 !ordered_set_isempty(network
->search_domains
) ||
664 !ordered_set_isempty(network
->route_domains
))
670 bool network_has_static_ipv6_addresses(Network
*network
) {
675 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
676 if (address
->family
== AF_INET6
)
683 int config_parse_stacked_netdev(const char *unit
,
684 const char *filename
,
687 unsigned section_line
,
693 _cleanup_free_
char *name
= NULL
;
694 NetDevKind kind
= ltype
;
703 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
704 NETDEV_KIND_IPVLAN
, NETDEV_KIND_VXLAN
, NETDEV_KIND_L2TP
,
705 NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
));
707 if (!ifname_valid(rvalue
)) {
708 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
709 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
713 name
= strdup(rvalue
);
717 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
721 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
723 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
724 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
726 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
727 "NetDev '%s' specified twice, ignoring.", name
);
734 int config_parse_domains(
736 const char *filename
,
739 unsigned section_line
,
754 if (isempty(rvalue
)) {
755 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
756 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
762 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
766 r
= extract_first_word(&p
, &w
, NULL
, 0);
768 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
769 "Failed to extract search or route domain, ignoring: %s", rvalue
);
775 is_route
= w
[0] == '~';
776 domain
= is_route
? w
+ 1 : w
;
778 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
779 /* If the root domain appears as is, or the special token "*" is found, we'll
780 * consider this as routing domain, unconditionally. */
782 domain
= "."; /* make sure we don't allow empty strings, thus write the root
785 r
= dns_name_normalize(domain
, 0, &normalized
);
787 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
788 "'%s' is not a valid domain name, ignoring.", domain
);
794 if (is_localhost(domain
)) {
795 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
796 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
802 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
803 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
807 r
= ordered_set_put_strdup(*set
, domain
);
815 int config_parse_ipv4ll(
817 const char *filename
,
820 unsigned section_line
,
827 AddressFamilyBoolean
*link_local
= data
;
835 /* Note that this is mostly like
836 * config_parse_address_family_boolean(), except that it
837 * applies only to IPv4 */
839 r
= parse_boolean(rvalue
);
841 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
842 "Failed to parse %s=%s, ignoring assignment. "
843 "Note that the setting %s= is deprecated, please use LinkLocalAddressing= instead.",
844 lvalue
, rvalue
, lvalue
);
848 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, r
);
850 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
851 "%s=%s is deprecated, please use LinkLocalAddressing=%s instead.",
852 lvalue
, rvalue
, address_family_boolean_to_string(*link_local
));
857 int config_parse_dhcp(
859 const char *filename
,
862 unsigned section_line
,
869 AddressFamilyBoolean
*dhcp
= data
, s
;
876 /* Note that this is mostly like
877 * config_parse_address_family_boolean(), except that it
878 * understands some old names for the enum values */
880 s
= address_family_boolean_from_string(rvalue
);
883 /* Previously, we had a slightly different enum here,
884 * support its values for compatibility. */
886 if (streq(rvalue
, "none"))
887 s
= ADDRESS_FAMILY_NO
;
888 else if (streq(rvalue
, "v4"))
889 s
= ADDRESS_FAMILY_IPV4
;
890 else if (streq(rvalue
, "v6"))
891 s
= ADDRESS_FAMILY_IPV6
;
892 else if (streq(rvalue
, "both"))
893 s
= ADDRESS_FAMILY_YES
;
895 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
896 "Failed to parse DHCP option, ignoring: %s", rvalue
);
900 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
901 "DHCP=%s is deprecated, please use DHCP=%s instead.",
902 rvalue
, address_family_boolean_to_string(s
));
909 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
910 [DHCP_CLIENT_ID_MAC
] = "mac",
911 [DHCP_CLIENT_ID_DUID
] = "duid",
912 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
915 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
916 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
917 "Failed to parse client identifier type");
919 int config_parse_ipv6token(
921 const char *filename
,
924 unsigned section_line
,
931 union in_addr_union buffer
;
932 struct in6_addr
*token
= data
;
940 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
942 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
943 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
947 if (in_addr_is_null(AF_INET6
, &buffer
)) {
948 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
949 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
953 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
954 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
955 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
964 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
965 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
966 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
967 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
970 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
972 int config_parse_ipv6_privacy_extensions(
974 const char *filename
,
977 unsigned section_line
,
984 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
990 assert(ipv6_privacy_extensions
);
992 /* Our enum shall be a superset of booleans, hence first try
993 * to parse as boolean, and then as enum */
995 k
= parse_boolean(rvalue
);
997 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
999 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
1001 IPv6PrivacyExtensions s
;
1003 s
= ipv6_privacy_extensions_from_string(rvalue
);
1006 if (streq(rvalue
, "kernel"))
1007 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1009 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1010 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1015 *ipv6_privacy_extensions
= s
;
1021 int config_parse_hostname(
1023 const char *filename
,
1025 const char *section
,
1026 unsigned section_line
,
1033 _cleanup_free_
char *hn
= NULL
;
1034 char **hostname
= data
;
1041 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1045 if (!hostname_is_valid(hn
, false)) {
1046 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1047 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1051 r
= dns_name_is_valid(hn
);
1053 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1054 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1058 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1059 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1063 return free_and_replace(*hostname
, hn
);
1066 int config_parse_timezone(
1068 const char *filename
,
1070 const char *section
,
1071 unsigned section_line
,
1078 _cleanup_free_
char *tz
= NULL
;
1079 char **datap
= data
;
1086 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1090 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1091 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1092 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1096 return free_and_replace(*datap
, tz
);
1099 int config_parse_dhcp_server_dns(
1101 const char *filename
,
1103 const char *section
,
1104 unsigned section_line
,
1112 const char *p
= rvalue
;
1120 _cleanup_free_
char *w
= NULL
;
1121 struct in_addr a
, *m
;
1123 r
= extract_first_word(&p
, &w
, NULL
, 0);
1127 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1128 "Failed to extract word, ignoring: %s", rvalue
);
1134 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1135 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1136 "Failed to parse DNS server address, ignoring: %s", w
);
1140 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1144 m
[n
->n_dhcp_server_dns
++] = a
;
1145 n
->dhcp_server_dns
= m
;
1151 int config_parse_radv_dns(
1153 const char *filename
,
1155 const char *section
,
1156 unsigned section_line
,
1164 const char *p
= rvalue
;
1172 _cleanup_free_
char *w
= NULL
;
1173 union in_addr_union a
;
1175 r
= extract_first_word(&p
, &w
, NULL
, 0);
1179 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1180 "Failed to extract word, ignoring: %s", rvalue
);
1186 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1189 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1193 m
[n
->n_router_dns
++] = a
.in6
;
1197 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1198 "Failed to parse DNS server address, ignoring: %s", w
);
1204 int config_parse_radv_search_domains(
1206 const char *filename
,
1208 const char *section
,
1209 unsigned section_line
,
1217 const char *p
= rvalue
;
1225 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1227 r
= extract_first_word(&p
, &w
, NULL
, 0);
1231 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1232 "Failed to extract word, ignoring: %s", rvalue
);
1238 r
= dns_name_apply_idna(w
, &idna
);
1240 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1241 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1244 /* transfer ownership to simplify subsequent operations */
1247 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1251 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1259 int config_parse_dhcp_server_ntp(
1261 const char *filename
,
1263 const char *section
,
1264 unsigned section_line
,
1272 const char *p
= rvalue
;
1280 _cleanup_free_
char *w
= NULL
;
1281 struct in_addr a
, *m
;
1283 r
= extract_first_word(&p
, &w
, NULL
, 0);
1287 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1288 "Failed to extract word, ignoring: %s", rvalue
);
1294 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1295 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1296 "Failed to parse NTP server address, ignoring: %s", w
);
1300 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1304 m
[n
->n_dhcp_server_ntp
++] = a
;
1305 n
->dhcp_server_ntp
= m
;
1309 int config_parse_dns(
1311 const char *filename
,
1313 const char *section
,
1314 unsigned section_line
,
1321 Network
*n
= userdata
;
1329 _cleanup_free_
char *w
= NULL
;
1330 union in_addr_union a
;
1331 struct in_addr_data
*m
;
1334 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1338 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1339 "Invalid syntax, ignoring: %s", rvalue
);
1345 r
= in_addr_from_string_auto(w
, &family
, &a
);
1347 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1348 "Failed to parse dns server address, ignoring: %s", w
);
1352 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1356 m
[n
->n_dns
++] = (struct in_addr_data
) {
1367 int config_parse_dnssec_negative_trust_anchors(
1369 const char *filename
,
1371 const char *section
,
1372 unsigned section_line
,
1379 const char *p
= rvalue
;
1387 if (isempty(rvalue
)) {
1388 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1393 _cleanup_free_
char *w
= NULL
;
1395 r
= extract_first_word(&p
, &w
, NULL
, 0);
1397 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1398 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1404 r
= dns_name_is_valid(w
);
1406 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1407 "%s is not a valid domain name, ignoring.", w
);
1411 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1415 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1425 int config_parse_ntp(
1427 const char *filename
,
1429 const char *section
,
1430 unsigned section_line
,
1444 if (isempty(rvalue
)) {
1450 _cleanup_free_
char *w
= NULL
;
1452 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1456 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1457 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1463 r
= dns_name_is_valid_or_address(w
);
1465 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1466 "%s is not a valid domain name or IP address, ignoring.", w
);
1470 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1471 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1472 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1473 MAX_NTP_SERVERS
, w
);
1477 r
= strv_consume(l
, TAKE_PTR(w
));
1485 int config_parse_dhcp_user_class(
1487 const char *filename
,
1489 const char *section
,
1490 unsigned section_line
,
1504 if (isempty(rvalue
)) {
1510 _cleanup_free_
char *w
= NULL
;
1512 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1516 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1517 "Failed to split user classes option, ignoring: %s", rvalue
);
1523 if (strlen(w
) > 255) {
1524 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1525 "%s length is not in the range 1-255, ignoring.", w
);
1529 r
= strv_push(l
, w
);
1539 int config_parse_section_route_table(
1541 const char *filename
,
1543 const char *section
,
1544 unsigned section_line
,
1551 Network
*network
= data
;
1560 r
= safe_atou32(rvalue
, &rt
);
1562 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1563 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1567 if (streq_ptr(section
, "DHCP")) {
1568 network
->dhcp_route_table
= rt
;
1569 network
->dhcp_route_table_set
= true;
1570 } else { /* section is IPv6AcceptRA */
1571 network
->ipv6_accept_ra_route_table
= rt
;
1572 network
->ipv6_accept_ra_route_table_set
= true;
1578 int config_parse_dhcp_max_attempts(
1580 const char *filename
,
1582 const char *section
,
1583 unsigned section_line
,
1590 Network
*network
= data
;
1598 if (isempty(rvalue
)) {
1599 network
->dhcp_max_attempts
= 0;
1603 if (streq(rvalue
, "infinity")) {
1604 network
->dhcp_max_attempts
= (uint64_t) -1;
1608 r
= safe_atou64(rvalue
, &a
);
1610 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1611 "Failed to parse DHCP maximum attempts, ignoring: %s", rvalue
);
1616 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1617 "%s= must be positive integer or 'infinity', ignoring: %s", lvalue
, rvalue
);
1621 network
->dhcp_max_attempts
= a
;
1626 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1627 "Failed to parse DHCP use domains setting");
1629 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1630 [DHCP_USE_DOMAINS_NO
] = "no",
1631 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1632 [DHCP_USE_DOMAINS_YES
] = "yes",
1635 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1637 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1639 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1640 [LLDP_MODE_NO
] = "no",
1641 [LLDP_MODE_YES
] = "yes",
1642 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1645 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
1647 int config_parse_iaid(const char *unit
,
1648 const char *filename
,
1650 const char *section
,
1651 unsigned section_line
,
1657 Network
*network
= data
;
1666 r
= safe_atou32(rvalue
, &iaid
);
1668 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1669 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1673 network
->iaid
= iaid
;
1674 network
->iaid_set
= true;
1679 int config_parse_required_for_online(
1681 const char *filename
,
1683 const char *section
,
1684 unsigned section_line
,
1691 Network
*network
= data
;
1692 LinkOperationalState s
;
1693 bool required
= true;
1696 if (isempty(rvalue
)) {
1697 network
->required_for_online
= true;
1698 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1702 s
= link_operstate_from_string(rvalue
);
1704 r
= parse_boolean(rvalue
);
1706 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1707 "Failed to parse %s= setting, ignoring assignment: %s",
1713 s
= LINK_OPERSTATE_DEGRADED
;
1716 network
->required_for_online
= required
;
1717 network
->required_operstate_for_online
= s
;