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
,
394 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
396 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
398 .dns_default_route
= -1,
399 .llmnr
= RESOLVE_SUPPORT_YES
,
400 .mdns
= RESOLVE_SUPPORT_NO
,
401 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
402 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
404 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
405 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
407 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
408 .ipv6_accept_ra
= -1,
409 .ipv6_dad_transmits
= -1,
410 .ipv6_hop_limit
= -1,
411 .ipv6_proxy_ndp
= -1,
412 .duid
.type
= _DUID_TYPE_INVALID
,
417 .ipv6_accept_ra_use_dns
= true,
418 .ipv6_accept_ra_use_autonomous_prefix
= true,
419 .ipv6_accept_ra_use_onlink_prefix
= true,
420 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
421 .ipv6_accept_ra_route_table_set
= false,
423 .can_triple_sampling
= -1,
426 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
433 "RoutingPolicyRule\0"
436 "DHCPv4\0" /* compat */
439 "IPv6NDPProxyAddress\0"
443 "IPv6PrefixDelegation\0"
446 config_item_perf_lookup
, network_network_gperf_lookup
,
447 CONFIG_PARSE_WARN
, network
);
451 network_apply_anonymize_if_set(network
);
453 r
= network_add_ipv4ll_route(network
);
455 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
457 r
= network_add_default_route_on_device(network
);
459 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
462 r
= ordered_hashmap_ensure_allocated(&manager
->networks
, &string_hash_ops
);
466 r
= ordered_hashmap_put(manager
->networks
, network
->name
, network
);
470 if (network_verify(network
) < 0)
477 int network_load(Manager
*manager
) {
478 _cleanup_strv_free_
char **files
= NULL
;
484 ordered_hashmap_clear_with_destructor(manager
->networks
, network_unref
);
486 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
488 return log_error_errno(r
, "Failed to enumerate network files: %m");
490 STRV_FOREACH(f
, files
) {
491 r
= network_load_one(manager
, *f
);
499 static Network
*network_free(Network
*network
) {
500 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
501 RoutingPolicyRule
*rule
;
512 free(network
->filename
);
514 set_free_free(network
->match_mac
);
515 strv_free(network
->match_path
);
516 strv_free(network
->match_driver
);
517 strv_free(network
->match_type
);
518 strv_free(network
->match_name
);
519 condition_free_list(network
->conditions
);
521 free(network
->description
);
522 free(network
->dhcp_vendor_class_identifier
);
523 strv_free(network
->dhcp_user_class
);
524 free(network
->dhcp_hostname
);
525 set_free(network
->dhcp_black_listed_ip
);
528 strv_free(network
->ntp
);
530 ordered_set_free_free(network
->search_domains
);
531 ordered_set_free_free(network
->route_domains
);
532 strv_free(network
->bind_carrier
);
534 ordered_set_free_free(network
->router_search_domains
);
535 free(network
->router_dns
);
537 free(network
->bridge_name
);
538 free(network
->bond_name
);
539 free(network
->vrf_name
);
540 hashmap_free_free_key(network
->stacked_netdev_names
);
541 netdev_unref(network
->bridge
);
542 netdev_unref(network
->bond
);
543 netdev_unref(network
->vrf
);
544 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
546 while ((route
= network
->static_routes
))
549 while ((address
= network
->static_addresses
))
550 address_free(address
);
552 while ((fdb_entry
= network
->static_fdb_entries
))
553 fdb_entry_free(fdb_entry
);
555 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
556 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
558 while ((neighbor
= network
->neighbors
))
559 neighbor_free(neighbor
);
561 while ((label
= network
->address_labels
))
562 address_label_free(label
);
564 while ((prefix
= network
->static_prefixes
))
567 while ((rule
= network
->rules
))
568 routing_policy_rule_free(rule
);
570 hashmap_free(network
->addresses_by_section
);
571 hashmap_free(network
->routes_by_section
);
572 hashmap_free(network
->fdb_entries_by_section
);
573 hashmap_free(network
->neighbors_by_section
);
574 hashmap_free(network
->address_labels_by_section
);
575 hashmap_free(network
->prefixes_by_section
);
576 hashmap_free(network
->rules_by_section
);
578 if (network
->manager
) {
579 if (network
->manager
->networks
&& network
->name
)
580 ordered_hashmap_remove(network
->manager
->networks
, network
->name
);
582 if (network
->manager
->duids_requesting_uuid
)
583 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
588 free(network
->dhcp_server_timezone
);
589 free(network
->dhcp_server_dns
);
590 free(network
->dhcp_server_ntp
);
592 set_free_free(network
->dnssec_negative_trust_anchors
);
594 return mfree(network
);
597 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
599 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
606 network
= ordered_hashmap_get(manager
->networks
, name
);
615 int network_get(Manager
*manager
, sd_device
*device
,
616 const char *ifname
, const struct ether_addr
*address
,
618 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
626 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
628 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
630 (void) sd_device_get_devtype(device
, &devtype
);
633 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
634 if (net_match_config(network
->match_mac
, network
->match_path
,
635 network
->match_driver
, network
->match_type
,
637 address
, path
, driver
, devtype
, ifname
)) {
638 if (network
->match_name
&& device
) {
640 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
642 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
643 (void) safe_atou8(attr
, &name_assign_type
);
645 if (name_assign_type
== NET_NAME_ENUM
)
646 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
647 ifname
, network
->filename
);
649 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
651 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
662 int network_apply(Network
*network
, Link
*link
) {
666 link
->network
= network_ref(network
);
668 if (network
->n_dns
> 0 ||
669 !strv_isempty(network
->ntp
) ||
670 !ordered_set_isempty(network
->search_domains
) ||
671 !ordered_set_isempty(network
->route_domains
))
677 bool network_has_static_ipv6_addresses(Network
*network
) {
682 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
683 if (address
->family
== AF_INET6
)
690 int config_parse_stacked_netdev(const char *unit
,
691 const char *filename
,
694 unsigned section_line
,
700 _cleanup_free_
char *name
= NULL
;
701 NetDevKind kind
= ltype
;
710 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
711 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
712 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
));
714 if (!ifname_valid(rvalue
)) {
715 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
716 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
720 name
= strdup(rvalue
);
724 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
728 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
730 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
731 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
733 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
734 "NetDev '%s' specified twice, ignoring.", name
);
741 int config_parse_domains(
743 const char *filename
,
746 unsigned section_line
,
761 if (isempty(rvalue
)) {
762 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
763 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
769 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
773 r
= extract_first_word(&p
, &w
, NULL
, 0);
775 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
776 "Failed to extract search or route domain, ignoring: %s", rvalue
);
782 is_route
= w
[0] == '~';
783 domain
= is_route
? w
+ 1 : w
;
785 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
786 /* If the root domain appears as is, or the special token "*" is found, we'll
787 * consider this as routing domain, unconditionally. */
789 domain
= "."; /* make sure we don't allow empty strings, thus write the root
792 r
= dns_name_normalize(domain
, 0, &normalized
);
794 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
795 "'%s' is not a valid domain name, ignoring.", domain
);
801 if (is_localhost(domain
)) {
802 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
803 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
809 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
810 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
814 r
= ordered_set_put_strdup(*set
, domain
);
822 int config_parse_ipv4ll(
824 const char *filename
,
827 unsigned section_line
,
834 AddressFamilyBoolean
*link_local
= data
;
842 /* Note that this is mostly like
843 * config_parse_address_family_boolean(), except that it
844 * applies only to IPv4 */
846 r
= parse_boolean(rvalue
);
848 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
849 "Failed to parse %s=%s, ignoring assignment. "
850 "Note that the setting %s= is deprecated, please use LinkLocalAddressing= instead.",
851 lvalue
, rvalue
, lvalue
);
855 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, r
);
857 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
858 "%s=%s is deprecated, please use LinkLocalAddressing=%s instead.",
859 lvalue
, rvalue
, address_family_boolean_to_string(*link_local
));
864 int config_parse_dhcp(
866 const char *filename
,
869 unsigned section_line
,
876 AddressFamilyBoolean
*dhcp
= data
, s
;
883 /* Note that this is mostly like
884 * config_parse_address_family_boolean(), except that it
885 * understands some old names for the enum values */
887 s
= address_family_boolean_from_string(rvalue
);
890 /* Previously, we had a slightly different enum here,
891 * support its values for compatibility. */
893 if (streq(rvalue
, "none"))
894 s
= ADDRESS_FAMILY_NO
;
895 else if (streq(rvalue
, "v4"))
896 s
= ADDRESS_FAMILY_IPV4
;
897 else if (streq(rvalue
, "v6"))
898 s
= ADDRESS_FAMILY_IPV6
;
899 else if (streq(rvalue
, "both"))
900 s
= ADDRESS_FAMILY_YES
;
902 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
903 "Failed to parse DHCP option, ignoring: %s", rvalue
);
907 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
908 "DHCP=%s is deprecated, please use DHCP=%s instead.",
909 rvalue
, address_family_boolean_to_string(s
));
916 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
917 [DHCP_CLIENT_ID_MAC
] = "mac",
918 [DHCP_CLIENT_ID_DUID
] = "duid",
919 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
922 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
923 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
924 "Failed to parse client identifier type");
926 int config_parse_ipv6token(
928 const char *filename
,
931 unsigned section_line
,
938 union in_addr_union buffer
;
939 struct in6_addr
*token
= data
;
947 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
949 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
950 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
954 if (in_addr_is_null(AF_INET6
, &buffer
)) {
955 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
956 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
960 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
961 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
962 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
971 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
972 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
973 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
974 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
977 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
979 int config_parse_ipv6_privacy_extensions(
981 const char *filename
,
984 unsigned section_line
,
991 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
997 assert(ipv6_privacy_extensions
);
999 /* Our enum shall be a superset of booleans, hence first try
1000 * to parse as boolean, and then as enum */
1002 k
= parse_boolean(rvalue
);
1004 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
1006 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
1008 IPv6PrivacyExtensions s
;
1010 s
= ipv6_privacy_extensions_from_string(rvalue
);
1013 if (streq(rvalue
, "kernel"))
1014 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1016 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1017 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1022 *ipv6_privacy_extensions
= s
;
1028 int config_parse_hostname(
1030 const char *filename
,
1032 const char *section
,
1033 unsigned section_line
,
1040 _cleanup_free_
char *hn
= NULL
;
1041 char **hostname
= data
;
1048 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1052 if (!hostname_is_valid(hn
, false)) {
1053 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1054 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1058 r
= dns_name_is_valid(hn
);
1060 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1061 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1065 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1066 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1070 return free_and_replace(*hostname
, hn
);
1073 int config_parse_timezone(
1075 const char *filename
,
1077 const char *section
,
1078 unsigned section_line
,
1085 _cleanup_free_
char *tz
= NULL
;
1086 char **datap
= data
;
1093 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1097 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1098 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1099 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1103 return free_and_replace(*datap
, tz
);
1106 int config_parse_dhcp_server_dns(
1108 const char *filename
,
1110 const char *section
,
1111 unsigned section_line
,
1119 const char *p
= rvalue
;
1127 _cleanup_free_
char *w
= NULL
;
1128 union in_addr_union a
;
1131 r
= extract_first_word(&p
, &w
, NULL
, 0);
1135 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1136 "Failed to extract word, ignoring: %s", rvalue
);
1142 r
= in_addr_from_string(AF_INET
, w
, &a
);
1144 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1145 "Failed to parse DNS server address '%s', ignoring assignment: %m", w
);
1149 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1153 m
[n
->n_dhcp_server_dns
++] = a
.in
;
1154 n
->dhcp_server_dns
= m
;
1160 int config_parse_radv_dns(
1162 const char *filename
,
1164 const char *section
,
1165 unsigned section_line
,
1173 const char *p
= rvalue
;
1181 _cleanup_free_
char *w
= NULL
;
1182 union in_addr_union a
;
1184 r
= extract_first_word(&p
, &w
, NULL
, 0);
1188 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1189 "Failed to extract word, ignoring: %s", rvalue
);
1195 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1198 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1202 m
[n
->n_router_dns
++] = a
.in6
;
1206 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1207 "Failed to parse DNS server address, ignoring: %s", w
);
1213 int config_parse_radv_search_domains(
1215 const char *filename
,
1217 const char *section
,
1218 unsigned section_line
,
1226 const char *p
= rvalue
;
1234 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1236 r
= extract_first_word(&p
, &w
, NULL
, 0);
1240 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1241 "Failed to extract word, ignoring: %s", rvalue
);
1247 r
= dns_name_apply_idna(w
, &idna
);
1249 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1250 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1253 /* transfer ownership to simplify subsequent operations */
1256 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1260 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1268 int config_parse_dhcp_server_ntp(
1270 const char *filename
,
1272 const char *section
,
1273 unsigned section_line
,
1281 const char *p
= rvalue
;
1289 _cleanup_free_
char *w
= NULL
;
1290 union in_addr_union a
;
1293 r
= extract_first_word(&p
, &w
, NULL
, 0);
1297 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1298 "Failed to extract word, ignoring: %s", rvalue
);
1304 r
= in_addr_from_string(AF_INET
, w
, &a
);
1306 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1307 "Failed to parse NTP server address '%s', ignoring: %m", w
);
1311 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1315 m
[n
->n_dhcp_server_ntp
++] = a
.in
;
1316 n
->dhcp_server_ntp
= m
;
1320 int config_parse_dns(
1322 const char *filename
,
1324 const char *section
,
1325 unsigned section_line
,
1332 Network
*n
= userdata
;
1340 _cleanup_free_
char *w
= NULL
;
1341 union in_addr_union a
;
1342 struct in_addr_data
*m
;
1345 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1349 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1350 "Invalid syntax, ignoring: %s", rvalue
);
1356 r
= in_addr_from_string_auto(w
, &family
, &a
);
1358 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1359 "Failed to parse dns server address, ignoring: %s", w
);
1363 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1367 m
[n
->n_dns
++] = (struct in_addr_data
) {
1378 int config_parse_dnssec_negative_trust_anchors(
1380 const char *filename
,
1382 const char *section
,
1383 unsigned section_line
,
1390 const char *p
= rvalue
;
1398 if (isempty(rvalue
)) {
1399 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1404 _cleanup_free_
char *w
= NULL
;
1406 r
= extract_first_word(&p
, &w
, NULL
, 0);
1408 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1409 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1415 r
= dns_name_is_valid(w
);
1417 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1418 "%s is not a valid domain name, ignoring.", w
);
1422 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1426 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1436 int config_parse_ntp(
1438 const char *filename
,
1440 const char *section
,
1441 unsigned section_line
,
1455 if (isempty(rvalue
)) {
1461 _cleanup_free_
char *w
= NULL
;
1463 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1467 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1468 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1474 r
= dns_name_is_valid_or_address(w
);
1476 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1477 "%s is not a valid domain name or IP address, ignoring.", w
);
1481 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1482 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1483 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1484 MAX_NTP_SERVERS
, w
);
1488 r
= strv_consume(l
, TAKE_PTR(w
));
1496 int config_parse_dhcp_user_class(
1498 const char *filename
,
1500 const char *section
,
1501 unsigned section_line
,
1515 if (isempty(rvalue
)) {
1521 _cleanup_free_
char *w
= NULL
;
1523 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1527 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1528 "Failed to split user classes option, ignoring: %s", rvalue
);
1534 if (strlen(w
) > 255) {
1535 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1536 "%s length is not in the range 1-255, ignoring.", w
);
1540 r
= strv_push(l
, w
);
1550 int config_parse_section_route_table(
1552 const char *filename
,
1554 const char *section
,
1555 unsigned section_line
,
1562 Network
*network
= data
;
1571 r
= safe_atou32(rvalue
, &rt
);
1573 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1574 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1578 if (streq_ptr(section
, "DHCP")) {
1579 network
->dhcp_route_table
= rt
;
1580 network
->dhcp_route_table_set
= true;
1581 } else { /* section is IPv6AcceptRA */
1582 network
->ipv6_accept_ra_route_table
= rt
;
1583 network
->ipv6_accept_ra_route_table_set
= true;
1589 int config_parse_dhcp_max_attempts(
1591 const char *filename
,
1593 const char *section
,
1594 unsigned section_line
,
1601 Network
*network
= data
;
1609 if (isempty(rvalue
)) {
1610 network
->dhcp_max_attempts
= 0;
1614 if (streq(rvalue
, "infinity")) {
1615 network
->dhcp_max_attempts
= (uint64_t) -1;
1619 r
= safe_atou64(rvalue
, &a
);
1621 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1622 "Failed to parse DHCP maximum attempts, ignoring: %s", rvalue
);
1627 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1628 "%s= must be positive integer or 'infinity', ignoring: %s", lvalue
, rvalue
);
1632 network
->dhcp_max_attempts
= a
;
1637 int config_parse_dhcp_black_listed_ip_address(
1639 const char *filename
,
1641 const char *section
,
1642 unsigned section_line
,
1649 Network
*network
= data
;
1658 if (isempty(rvalue
)) {
1659 network
->dhcp_black_listed_ip
= set_free(network
->dhcp_black_listed_ip
);
1663 for (p
= rvalue
;;) {
1664 _cleanup_free_
char *n
= NULL
;
1665 union in_addr_union ip
;
1667 r
= extract_first_word(&p
, &n
, NULL
, 0);
1669 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1670 "Failed to parse DHCP black listed ip address, ignoring assignment: %s",
1677 r
= in_addr_from_string(AF_INET
, n
, &ip
);
1679 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1680 "DHCP black listed ip address is invalid, ignoring assignment: %s", n
);
1684 r
= set_ensure_allocated(&network
->dhcp_black_listed_ip
, NULL
);
1688 r
= set_put(network
->dhcp_black_listed_ip
, UINT32_TO_PTR(ip
.in
.s_addr
));
1690 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1691 "DHCP black listed ip address is duplicated, ignoring assignment: %s", n
);
1695 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1696 "Failed to store DHCP black listed ip address '%s', ignoring assignment: %m", n
);
1702 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1703 "Failed to parse DHCP use domains setting");
1705 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1706 [DHCP_USE_DOMAINS_NO
] = "no",
1707 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1708 [DHCP_USE_DOMAINS_YES
] = "yes",
1711 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1713 int config_parse_iaid(const char *unit
,
1714 const char *filename
,
1716 const char *section
,
1717 unsigned section_line
,
1723 Network
*network
= data
;
1732 r
= safe_atou32(rvalue
, &iaid
);
1734 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1735 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1739 network
->iaid
= iaid
;
1740 network
->iaid_set
= true;
1745 int config_parse_required_for_online(
1747 const char *filename
,
1749 const char *section
,
1750 unsigned section_line
,
1757 Network
*network
= data
;
1758 LinkOperationalState s
;
1759 bool required
= true;
1762 if (isempty(rvalue
)) {
1763 network
->required_for_online
= true;
1764 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1768 s
= link_operstate_from_string(rvalue
);
1770 r
= parse_boolean(rvalue
);
1772 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1773 "Failed to parse %s= setting, ignoring assignment: %s",
1779 s
= LINK_OPERSTATE_DEGRADED
;
1782 network
->required_for_online
= required
;
1783 network
->required_operstate_for_online
= s
;