1 /* SPDX-License-Identifier: LGPL-2.1+ */
4 #include <netinet/in.h>
5 #include <linux/netdevice.h>
7 #include "alloc-util.h"
8 #include "conf-files.h"
9 #include "conf-parser.h"
10 #include "dns-domain.h"
12 #include "hostname-util.h"
13 #include "in-addr-util.h"
14 #include "network-internal.h"
15 #include "networkd-manager.h"
16 #include "networkd-network.h"
17 #include "parse-util.h"
19 #include "socket-util.h"
20 #include "stat-util.h"
21 #include "string-table.h"
22 #include "string-util.h"
26 /* Let's assume that anything above this number is a user misconfiguration. */
27 #define MAX_NTP_SERVERS 128
29 /* Set defaults following RFC7844 */
30 void network_apply_anonymize_if_set(Network
*network
) {
31 if (!network
->dhcp_anonymize
)
34 SHOULD NOT send the Host Name option */
35 network
->dhcp_send_hostname
= false;
36 /* RFC7844 section 3.:
37 MAY contain the Client Identifier option
39 clients MUST use client identifiers based solely
40 on the link-layer address */
41 /* NOTE: Using MAC, as it does not reveal extra information,
42 * and some servers might not answer if this option is not sent */
43 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
45 SHOULD NOT use the Vendor Class Identifier option */
46 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
47 /* RFC7844 section 3.6.:
48 The client intending to protect its privacy SHOULD only request a
49 minimal number of options in the PRL and SHOULD also randomly shuffle
50 the ordering of option codes in the PRL. If this random ordering
51 cannot be implemented, the client MAY order the option codes in the
52 PRL by option code number (lowest to highest).
54 /* NOTE: dhcp_use_mtu is false by default,
55 * though it was not initiallized to any value in network_load_one.
56 * Maybe there should be another var called *send*?
57 * (to use the MTU sent by the server but to do not send
58 * the option in the PRL). */
59 network
->dhcp_use_mtu
= false;
60 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
61 * but this is needed to use them. */
62 network
->dhcp_use_routes
= true;
63 /* RFC7844 section 3.6.
64 * same comments as previous option */
65 network
->dhcp_use_timezone
= false;
68 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
69 const char *kind_string
;
73 /* For test-networkd-conf, the check must be earlier than the assertions. */
78 assert(network
->manager
);
79 assert(network
->filename
);
82 if (kind
== _NETDEV_KIND_TUNNEL
)
83 kind_string
= "tunnel";
85 kind_string
= netdev_kind_to_string(kind
);
87 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
88 "%s: Invalid NetDev kind of %s, ignoring assignment.",
89 network
->filename
, name
);
92 r
= netdev_get(network
->manager
, name
, &netdev
);
94 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
95 network
->filename
, name
);
97 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
104 NETDEV_KIND_IP6GRETAP
,
108 NETDEV_KIND_ERSPAN
)))
109 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
110 "%s: NetDev %s is not a %s, ignoring assignment",
111 network
->filename
, name
, kind_string
);
113 *ret_netdev
= netdev_ref(netdev
);
117 static int network_resolve_stacked_netdevs(Network
*network
) {
124 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
125 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
127 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
131 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
135 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
137 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
138 network
->filename
, (const char *) name
);
146 int network_verify(Network
*network
) {
147 Address
*address
, *address_next
;
148 Route
*route
, *route_next
;
149 FdbEntry
*fdb
, *fdb_next
;
150 Neighbor
*neighbor
, *neighbor_next
;
151 AddressLabel
*label
, *label_next
;
152 Prefix
*prefix
, *prefix_next
;
153 RoutingPolicyRule
*rule
, *rule_next
;
156 assert(network
->filename
);
158 if (set_isempty(network
->match_mac
) && strv_isempty(network
->match_path
) &&
159 strv_isempty(network
->match_driver
) && strv_isempty(network
->match_type
) &&
160 strv_isempty(network
->match_name
) && !network
->conditions
)
161 log_warning("%s: No valid settings found in the [Match] section. "
162 "The file will match all interfaces. "
163 "If that is intended, please add Name=* in the [Match] section.",
166 /* skip out early if configuration does not match the environment */
167 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
168 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
169 "%s: Conditions in the file do not match the system environment, skipping.",
172 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
173 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
174 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
175 (void) network_resolve_stacked_netdevs(network
);
177 /* Free unnecessary entries. */
178 network
->bond_name
= mfree(network
->bond_name
);
179 network
->bridge_name
= mfree(network
->bridge_name
);
180 network
->vrf_name
= mfree(network
->vrf_name
);
181 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
184 /* Bonding slave does not support addressing. */
185 if (network
->ipv6_accept_ra
> 0) {
186 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
188 network
->ipv6_accept_ra
= 0;
190 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
191 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
193 network
->link_local
= ADDRESS_FAMILY_NO
;
195 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
196 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
198 network
->dhcp
= ADDRESS_FAMILY_NO
;
200 if (network
->dhcp_server
) {
201 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
203 network
->dhcp_server
= false;
205 if (network
->n_static_addresses
> 0) {
206 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
208 while ((address
= network
->static_addresses
))
209 address_free(address
);
211 if (network
->n_static_routes
> 0) {
212 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
214 while ((route
= network
->static_routes
))
219 if (network
->link_local
< 0)
220 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
222 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
223 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
224 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
225 "Disabling the fallback assignment.", network
->filename
);
226 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
229 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
230 network
->ipv6_accept_ra
= false;
232 /* IPMasquerade=yes implies IPForward=yes */
233 if (network
->ip_masquerade
)
234 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
236 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
237 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
238 "Disabling UseMTU=.", network
->filename
);
239 network
->dhcp_use_mtu
= false;
242 if (network
->dhcp_critical
>= 0) {
243 if (network
->keep_configuration
>= 0)
244 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
245 "Ignoring CriticalConnection=.", network
->filename
);
246 else if (network
->dhcp_critical
)
247 /* CriticalConnection=yes also preserve foreign static configurations. */
248 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
250 /* For backward compatibility, we do not release DHCP addresses on manager stop. */
251 network
->keep_configuration
= KEEP_CONFIGURATION_DHCP_ON_STOP
;
254 if (network
->keep_configuration
< 0)
255 /* For backward compatibility, we do not release DHCP addresses on manager stop. */
256 network
->keep_configuration
= KEEP_CONFIGURATION_DHCP_ON_STOP
;
258 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
259 if (address_section_verify(address
) < 0)
260 address_free(address
);
262 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
263 if (route_section_verify(route
, network
) < 0)
266 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
267 if (section_is_invalid(fdb
->section
))
270 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
271 if (section_is_invalid(neighbor
->section
))
272 neighbor_free(neighbor
);
274 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
275 if (section_is_invalid(label
->section
))
276 address_label_free(label
);
278 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
279 if (section_is_invalid(prefix
->section
))
282 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
283 if (section_is_invalid(rule
->section
))
284 routing_policy_rule_free(rule
);
289 int network_load_one(Manager
*manager
, const char *filename
) {
290 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
291 _cleanup_(network_unrefp
) Network
*network
= NULL
;
292 _cleanup_fclose_
FILE *file
= NULL
;
293 const char *dropin_dirname
;
300 file
= fopen(filename
, "re");
308 if (null_or_empty_fd(fileno(file
))) {
309 log_debug("Skipping empty file: %s", filename
);
313 fname
= strdup(filename
);
317 name
= strdup(basename(filename
));
321 d
= strrchr(name
, '.');
327 dropin_dirname
= strjoina(name
, ".network.d");
329 network
= new(Network
, 1);
333 *network
= (Network
) {
334 .filename
= TAKE_PTR(fname
),
335 .name
= TAKE_PTR(name
),
340 .required_for_online
= true,
341 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
342 .dhcp
= ADDRESS_FAMILY_NO
,
344 .dhcp_use_ntp
= true,
345 .dhcp_use_dns
= true,
346 .dhcp_use_hostname
= true,
347 .dhcp_use_routes
= true,
348 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
349 .dhcp_send_hostname
= true,
350 /* To enable/disable RFC7844 Anonymity Profiles */
351 .dhcp_anonymize
= false,
352 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
353 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
354 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
355 .dhcp_route_table
= RT_TABLE_MAIN
,
356 .dhcp_route_table_set
= false,
357 /* NOTE: from man: UseMTU=... Defaults to false*/
358 .dhcp_use_mtu
= false,
359 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
360 .dhcp_use_timezone
= false,
361 .rapid_commit
= true,
363 .dhcp_server_emit_dns
= true,
364 .dhcp_server_emit_ntp
= true,
365 .dhcp_server_emit_router
= true,
366 .dhcp_server_emit_timezone
= true,
368 .router_emit_dns
= true,
369 .router_emit_domains
= true,
374 .allow_port_to_be_root
= -1,
376 .multicast_flood
= -1,
377 .multicast_to_unicast
= -1,
378 .neighbor_suppression
= -1,
380 .bridge_proxy_arp
= -1,
381 .bridge_proxy_arp_wifi
= -1,
382 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
383 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
385 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
387 .dns_default_route
= -1,
388 .llmnr
= RESOLVE_SUPPORT_YES
,
389 .mdns
= RESOLVE_SUPPORT_NO
,
390 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
391 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
393 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
394 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
396 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
397 .ipv6_accept_ra
= -1,
398 .ipv6_dad_transmits
= -1,
399 .ipv6_hop_limit
= -1,
400 .ipv6_proxy_ndp
= -1,
401 .duid
.type
= _DUID_TYPE_INVALID
,
406 .ipv6_accept_ra_use_dns
= true,
407 .ipv6_accept_ra_use_autonomous_prefix
= true,
408 .ipv6_accept_ra_use_onlink_prefix
= true,
409 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
410 .ipv6_accept_ra_route_table_set
= false,
412 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
414 .can_triple_sampling
= -1,
417 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
424 "RoutingPolicyRule\0"
427 "DHCPv4\0" /* compat */
430 "IPv6NDPProxyAddress\0"
434 "IPv6PrefixDelegation\0"
437 config_item_perf_lookup
, network_network_gperf_lookup
,
438 CONFIG_PARSE_WARN
, network
);
442 network_apply_anonymize_if_set(network
);
444 r
= network_add_ipv4ll_route(network
);
446 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
448 r
= network_add_default_route_on_device(network
);
450 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
453 r
= ordered_hashmap_ensure_allocated(&manager
->networks
, &string_hash_ops
);
457 r
= ordered_hashmap_put(manager
->networks
, network
->name
, network
);
461 if (network_verify(network
) < 0)
468 int network_load(Manager
*manager
) {
469 _cleanup_strv_free_
char **files
= NULL
;
475 ordered_hashmap_clear_with_destructor(manager
->networks
, network_unref
);
477 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
479 return log_error_errno(r
, "Failed to enumerate network files: %m");
481 STRV_FOREACH(f
, files
) {
482 r
= network_load_one(manager
, *f
);
490 static Network
*network_free(Network
*network
) {
491 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
492 RoutingPolicyRule
*rule
;
503 free(network
->filename
);
505 set_free_free(network
->match_mac
);
506 strv_free(network
->match_path
);
507 strv_free(network
->match_driver
);
508 strv_free(network
->match_type
);
509 strv_free(network
->match_name
);
510 condition_free_list(network
->conditions
);
512 free(network
->description
);
513 free(network
->dhcp_vendor_class_identifier
);
514 strv_free(network
->dhcp_user_class
);
515 free(network
->dhcp_hostname
);
516 set_free(network
->dhcp_black_listed_ip
);
519 strv_free(network
->ntp
);
521 ordered_set_free_free(network
->search_domains
);
522 ordered_set_free_free(network
->route_domains
);
523 strv_free(network
->bind_carrier
);
525 ordered_set_free_free(network
->router_search_domains
);
526 free(network
->router_dns
);
527 set_free_free(network
->ndisc_black_listed_prefix
);
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
&& network
->name
)
572 ordered_hashmap_remove(network
->manager
->networks
, network
->name
);
574 if (network
->manager
->duids_requesting_uuid
)
575 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
580 free(network
->dhcp_server_timezone
);
581 free(network
->dhcp_server_dns
);
582 free(network
->dhcp_server_ntp
);
584 set_free_free(network
->dnssec_negative_trust_anchors
);
586 return mfree(network
);
589 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
591 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
598 network
= ordered_hashmap_get(manager
->networks
, name
);
607 int network_get(Manager
*manager
, sd_device
*device
,
608 const char *ifname
, const struct ether_addr
*address
,
610 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 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
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
);
654 int network_apply(Network
*network
, Link
*link
) {
658 link
->network
= network_ref(network
);
660 if (network
->n_dns
> 0 ||
661 !strv_isempty(network
->ntp
) ||
662 !ordered_set_isempty(network
->search_domains
) ||
663 !ordered_set_isempty(network
->route_domains
))
669 bool network_has_static_ipv6_addresses(Network
*network
) {
674 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
675 if (address
->family
== AF_INET6
)
682 int config_parse_stacked_netdev(const char *unit
,
683 const char *filename
,
686 unsigned section_line
,
692 _cleanup_free_
char *name
= NULL
;
693 NetDevKind kind
= ltype
;
702 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
703 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
704 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
));
706 if (!ifname_valid(rvalue
)) {
707 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
708 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
712 name
= strdup(rvalue
);
716 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
720 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
722 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
723 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
725 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
726 "NetDev '%s' specified twice, ignoring.", name
);
733 int config_parse_domains(
735 const char *filename
,
738 unsigned section_line
,
753 if (isempty(rvalue
)) {
754 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
755 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
761 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
765 r
= extract_first_word(&p
, &w
, NULL
, 0);
767 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
768 "Failed to extract search or route domain, ignoring: %s", rvalue
);
774 is_route
= w
[0] == '~';
775 domain
= is_route
? w
+ 1 : w
;
777 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
778 /* If the root domain appears as is, or the special token "*" is found, we'll
779 * consider this as routing domain, unconditionally. */
781 domain
= "."; /* make sure we don't allow empty strings, thus write the root
784 r
= dns_name_normalize(domain
, 0, &normalized
);
786 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
787 "'%s' is not a valid domain name, ignoring.", domain
);
793 if (is_localhost(domain
)) {
794 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
795 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
801 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
802 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
806 r
= ordered_set_put_strdup(*set
, domain
);
814 int config_parse_ipv4ll(
816 const char *filename
,
819 unsigned section_line
,
826 AddressFamilyBoolean
*link_local
= data
;
834 /* Note that this is mostly like
835 * config_parse_address_family_boolean(), except that it
836 * applies only to IPv4 */
838 r
= parse_boolean(rvalue
);
840 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
841 "Failed to parse %s=%s, ignoring assignment. "
842 "Note that the setting %s= is deprecated, please use LinkLocalAddressing= instead.",
843 lvalue
, rvalue
, lvalue
);
847 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, r
);
849 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
850 "%s=%s is deprecated, please use LinkLocalAddressing=%s instead.",
851 lvalue
, rvalue
, address_family_boolean_to_string(*link_local
));
856 int config_parse_dhcp(
858 const char *filename
,
861 unsigned section_line
,
868 AddressFamilyBoolean
*dhcp
= data
, s
;
875 /* Note that this is mostly like
876 * config_parse_address_family_boolean(), except that it
877 * understands some old names for the enum values */
879 s
= address_family_boolean_from_string(rvalue
);
882 /* Previously, we had a slightly different enum here,
883 * support its values for compatibility. */
885 if (streq(rvalue
, "none"))
886 s
= ADDRESS_FAMILY_NO
;
887 else if (streq(rvalue
, "v4"))
888 s
= ADDRESS_FAMILY_IPV4
;
889 else if (streq(rvalue
, "v6"))
890 s
= ADDRESS_FAMILY_IPV6
;
891 else if (streq(rvalue
, "both"))
892 s
= ADDRESS_FAMILY_YES
;
894 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
895 "Failed to parse DHCP option, ignoring: %s", rvalue
);
899 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
900 "DHCP=%s is deprecated, please use DHCP=%s instead.",
901 rvalue
, address_family_boolean_to_string(s
));
908 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
909 [DHCP_CLIENT_ID_MAC
] = "mac",
910 [DHCP_CLIENT_ID_DUID
] = "duid",
911 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
914 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
915 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
916 "Failed to parse client identifier type");
918 int config_parse_ipv6token(
920 const char *filename
,
923 unsigned section_line
,
930 union in_addr_union buffer
;
931 struct in6_addr
*token
= data
;
939 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
941 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
942 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
946 if (in_addr_is_null(AF_INET6
, &buffer
)) {
947 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
948 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
952 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
953 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
954 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
963 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
964 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
965 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
966 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
969 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
971 int config_parse_ipv6_privacy_extensions(
973 const char *filename
,
976 unsigned section_line
,
983 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
989 assert(ipv6_privacy_extensions
);
991 /* Our enum shall be a superset of booleans, hence first try
992 * to parse as boolean, and then as enum */
994 k
= parse_boolean(rvalue
);
996 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
998 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
1000 IPv6PrivacyExtensions s
;
1002 s
= ipv6_privacy_extensions_from_string(rvalue
);
1005 if (streq(rvalue
, "kernel"))
1006 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1008 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1009 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1014 *ipv6_privacy_extensions
= s
;
1020 int config_parse_hostname(
1022 const char *filename
,
1024 const char *section
,
1025 unsigned section_line
,
1032 _cleanup_free_
char *hn
= NULL
;
1033 char **hostname
= data
;
1040 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1044 if (!hostname_is_valid(hn
, false)) {
1045 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1046 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1050 r
= dns_name_is_valid(hn
);
1052 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1053 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1057 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1058 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1062 return free_and_replace(*hostname
, hn
);
1065 int config_parse_timezone(
1067 const char *filename
,
1069 const char *section
,
1070 unsigned section_line
,
1077 _cleanup_free_
char *tz
= NULL
;
1078 char **datap
= data
;
1085 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1089 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1090 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1091 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1095 return free_and_replace(*datap
, tz
);
1098 int config_parse_dhcp_server_dns(
1100 const char *filename
,
1102 const char *section
,
1103 unsigned section_line
,
1111 const char *p
= rvalue
;
1119 _cleanup_free_
char *w
= NULL
;
1120 union in_addr_union a
;
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 r
= in_addr_from_string(AF_INET
, w
, &a
);
1136 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1137 "Failed to parse DNS server address '%s', ignoring assignment: %m", w
);
1141 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1145 m
[n
->n_dhcp_server_dns
++] = a
.in
;
1146 n
->dhcp_server_dns
= m
;
1152 int config_parse_radv_dns(
1154 const char *filename
,
1156 const char *section
,
1157 unsigned section_line
,
1165 const char *p
= rvalue
;
1173 _cleanup_free_
char *w
= NULL
;
1174 union in_addr_union a
;
1176 r
= extract_first_word(&p
, &w
, NULL
, 0);
1180 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1181 "Failed to extract word, ignoring: %s", rvalue
);
1187 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1190 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1194 m
[n
->n_router_dns
++] = a
.in6
;
1198 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1199 "Failed to parse DNS server address, ignoring: %s", w
);
1205 int config_parse_radv_search_domains(
1207 const char *filename
,
1209 const char *section
,
1210 unsigned section_line
,
1218 const char *p
= rvalue
;
1226 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1228 r
= extract_first_word(&p
, &w
, NULL
, 0);
1232 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1233 "Failed to extract word, ignoring: %s", rvalue
);
1239 r
= dns_name_apply_idna(w
, &idna
);
1241 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1242 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1245 /* transfer ownership to simplify subsequent operations */
1248 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1252 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1260 int config_parse_dhcp_server_ntp(
1262 const char *filename
,
1264 const char *section
,
1265 unsigned section_line
,
1273 const char *p
= rvalue
;
1281 _cleanup_free_
char *w
= NULL
;
1282 union in_addr_union a
;
1285 r
= extract_first_word(&p
, &w
, NULL
, 0);
1289 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1290 "Failed to extract word, ignoring: %s", rvalue
);
1296 r
= in_addr_from_string(AF_INET
, w
, &a
);
1298 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1299 "Failed to parse NTP server address '%s', ignoring: %m", w
);
1303 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1307 m
[n
->n_dhcp_server_ntp
++] = a
.in
;
1308 n
->dhcp_server_ntp
= m
;
1312 int config_parse_dns(
1314 const char *filename
,
1316 const char *section
,
1317 unsigned section_line
,
1324 Network
*n
= userdata
;
1332 _cleanup_free_
char *w
= NULL
;
1333 union in_addr_union a
;
1334 struct in_addr_data
*m
;
1337 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1341 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1342 "Invalid syntax, ignoring: %s", rvalue
);
1348 r
= in_addr_from_string_auto(w
, &family
, &a
);
1350 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1351 "Failed to parse dns server address, ignoring: %s", w
);
1355 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1359 m
[n
->n_dns
++] = (struct in_addr_data
) {
1370 int config_parse_dnssec_negative_trust_anchors(
1372 const char *filename
,
1374 const char *section
,
1375 unsigned section_line
,
1382 const char *p
= rvalue
;
1390 if (isempty(rvalue
)) {
1391 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1396 _cleanup_free_
char *w
= NULL
;
1398 r
= extract_first_word(&p
, &w
, NULL
, 0);
1400 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1401 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1407 r
= dns_name_is_valid(w
);
1409 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1410 "%s is not a valid domain name, ignoring.", w
);
1414 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1418 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1428 int config_parse_ntp(
1430 const char *filename
,
1432 const char *section
,
1433 unsigned section_line
,
1447 if (isempty(rvalue
)) {
1453 _cleanup_free_
char *w
= NULL
;
1455 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1459 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1460 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1466 r
= dns_name_is_valid_or_address(w
);
1468 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1469 "%s is not a valid domain name or IP address, ignoring.", w
);
1473 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1474 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1475 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1476 MAX_NTP_SERVERS
, w
);
1480 r
= strv_consume(l
, TAKE_PTR(w
));
1488 int config_parse_dhcp_user_class(
1490 const char *filename
,
1492 const char *section
,
1493 unsigned section_line
,
1507 if (isempty(rvalue
)) {
1513 _cleanup_free_
char *w
= NULL
;
1515 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1519 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1520 "Failed to split user classes option, ignoring: %s", rvalue
);
1526 if (strlen(w
) > 255) {
1527 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1528 "%s length is not in the range 1-255, ignoring.", w
);
1532 r
= strv_push(l
, w
);
1542 int config_parse_section_route_table(
1544 const char *filename
,
1546 const char *section
,
1547 unsigned section_line
,
1554 Network
*network
= data
;
1563 r
= safe_atou32(rvalue
, &rt
);
1565 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1566 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1570 if (streq_ptr(section
, "DHCP")) {
1571 network
->dhcp_route_table
= rt
;
1572 network
->dhcp_route_table_set
= true;
1573 } else { /* section is IPv6AcceptRA */
1574 network
->ipv6_accept_ra_route_table
= rt
;
1575 network
->ipv6_accept_ra_route_table_set
= true;
1581 int config_parse_dhcp_max_attempts(
1583 const char *filename
,
1585 const char *section
,
1586 unsigned section_line
,
1593 Network
*network
= data
;
1601 if (isempty(rvalue
)) {
1602 network
->dhcp_max_attempts
= 0;
1606 if (streq(rvalue
, "infinity")) {
1607 network
->dhcp_max_attempts
= (uint64_t) -1;
1611 r
= safe_atou64(rvalue
, &a
);
1613 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1614 "Failed to parse DHCP maximum attempts, ignoring: %s", rvalue
);
1619 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1620 "%s= must be positive integer or 'infinity', ignoring: %s", lvalue
, rvalue
);
1624 network
->dhcp_max_attempts
= a
;
1629 int config_parse_dhcp_black_listed_ip_address(
1631 const char *filename
,
1633 const char *section
,
1634 unsigned section_line
,
1641 Network
*network
= data
;
1650 if (isempty(rvalue
)) {
1651 network
->dhcp_black_listed_ip
= set_free(network
->dhcp_black_listed_ip
);
1655 for (p
= rvalue
;;) {
1656 _cleanup_free_
char *n
= NULL
;
1657 union in_addr_union ip
;
1659 r
= extract_first_word(&p
, &n
, NULL
, 0);
1661 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1662 "Failed to parse DHCP black listed ip address, ignoring assignment: %s",
1669 r
= in_addr_from_string(AF_INET
, n
, &ip
);
1671 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1672 "DHCP black listed ip address is invalid, ignoring assignment: %s", n
);
1676 r
= set_ensure_allocated(&network
->dhcp_black_listed_ip
, NULL
);
1680 r
= set_put(network
->dhcp_black_listed_ip
, UINT32_TO_PTR(ip
.in
.s_addr
));
1682 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1683 "Failed to store DHCP black listed ip address '%s', ignoring assignment: %m", n
);
1689 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1690 "Failed to parse DHCP use domains setting");
1692 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1693 [DHCP_USE_DOMAINS_NO
] = "no",
1694 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1695 [DHCP_USE_DOMAINS_YES
] = "yes",
1698 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1700 int config_parse_iaid(const char *unit
,
1701 const char *filename
,
1703 const char *section
,
1704 unsigned section_line
,
1710 Network
*network
= data
;
1719 r
= safe_atou32(rvalue
, &iaid
);
1721 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1722 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1726 network
->iaid
= iaid
;
1727 network
->iaid_set
= true;
1732 int config_parse_required_for_online(
1734 const char *filename
,
1736 const char *section
,
1737 unsigned section_line
,
1744 Network
*network
= data
;
1745 LinkOperationalState s
;
1746 bool required
= true;
1749 if (isempty(rvalue
)) {
1750 network
->required_for_online
= true;
1751 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1755 s
= link_operstate_from_string(rvalue
);
1757 r
= parse_boolean(rvalue
);
1759 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1760 "Failed to parse %s= setting, ignoring assignment: %s",
1766 s
= LINK_OPERSTATE_DEGRADED
;
1769 network
->required_for_online
= required
;
1770 network
->required_operstate_for_online
= s
;
1775 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1776 "Failed to parse KeepConfiguration= setting");
1778 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1779 [KEEP_CONFIGURATION_NO
] = "no",
1780 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1781 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1782 [KEEP_CONFIGURATION_STATIC
] = "static",
1783 [KEEP_CONFIGURATION_YES
] = "yes",
1786 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);