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
= ordered_hashmap_ensure_allocated(&manager
->networks
, &string_hash_ops
);
461 r
= ordered_hashmap_put(manager
->networks
, network
->name
, network
);
465 if (network_verify(network
) < 0)
472 int network_load(Manager
*manager
) {
473 _cleanup_strv_free_
char **files
= NULL
;
479 ordered_hashmap_clear_with_destructor(manager
->networks
, network_unref
);
481 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
483 return log_error_errno(r
, "Failed to enumerate network files: %m");
485 STRV_FOREACH(f
, files
) {
486 r
= network_load_one(manager
, *f
);
494 static Network
*network_free(Network
*network
) {
495 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
496 RoutingPolicyRule
*rule
;
507 free(network
->filename
);
509 set_free_free(network
->match_mac
);
510 strv_free(network
->match_path
);
511 strv_free(network
->match_driver
);
512 strv_free(network
->match_type
);
513 strv_free(network
->match_name
);
514 condition_free_list(network
->conditions
);
516 free(network
->description
);
517 free(network
->dhcp_vendor_class_identifier
);
518 strv_free(network
->dhcp_user_class
);
519 free(network
->dhcp_hostname
);
520 set_free(network
->dhcp_black_listed_ip
);
523 strv_free(network
->ntp
);
525 ordered_set_free_free(network
->search_domains
);
526 ordered_set_free_free(network
->route_domains
);
527 strv_free(network
->bind_carrier
);
529 ordered_set_free_free(network
->router_search_domains
);
530 free(network
->router_dns
);
532 free(network
->bridge_name
);
533 free(network
->bond_name
);
534 free(network
->vrf_name
);
535 hashmap_free_free_key(network
->stacked_netdev_names
);
536 netdev_unref(network
->bridge
);
537 netdev_unref(network
->bond
);
538 netdev_unref(network
->vrf
);
539 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
541 while ((route
= network
->static_routes
))
544 while ((address
= network
->static_addresses
))
545 address_free(address
);
547 while ((fdb_entry
= network
->static_fdb_entries
))
548 fdb_entry_free(fdb_entry
);
550 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
551 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
553 while ((neighbor
= network
->neighbors
))
554 neighbor_free(neighbor
);
556 while ((label
= network
->address_labels
))
557 address_label_free(label
);
559 while ((prefix
= network
->static_prefixes
))
562 while ((rule
= network
->rules
))
563 routing_policy_rule_free(rule
);
565 hashmap_free(network
->addresses_by_section
);
566 hashmap_free(network
->routes_by_section
);
567 hashmap_free(network
->fdb_entries_by_section
);
568 hashmap_free(network
->neighbors_by_section
);
569 hashmap_free(network
->address_labels_by_section
);
570 hashmap_free(network
->prefixes_by_section
);
571 hashmap_free(network
->rules_by_section
);
573 if (network
->manager
) {
574 if (network
->manager
->networks
&& network
->name
)
575 ordered_hashmap_remove(network
->manager
->networks
, 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
);
589 return mfree(network
);
592 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
594 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
601 network
= ordered_hashmap_get(manager
->networks
, name
);
610 int network_get(Manager
*manager
, sd_device
*device
,
611 const char *ifname
, const struct ether_addr
*address
,
613 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
621 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
623 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
625 (void) sd_device_get_devtype(device
, &devtype
);
628 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
629 if (net_match_config(network
->match_mac
, network
->match_path
,
630 network
->match_driver
, network
->match_type
,
632 address
, path
, driver
, devtype
, ifname
)) {
633 if (network
->match_name
&& device
) {
635 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
637 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
638 (void) safe_atou8(attr
, &name_assign_type
);
640 if (name_assign_type
== NET_NAME_ENUM
)
641 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
642 ifname
, network
->filename
);
644 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
646 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
657 int network_apply(Network
*network
, Link
*link
) {
661 link
->network
= network_ref(network
);
663 if (network
->n_dns
> 0 ||
664 !strv_isempty(network
->ntp
) ||
665 !ordered_set_isempty(network
->search_domains
) ||
666 !ordered_set_isempty(network
->route_domains
))
672 bool network_has_static_ipv6_addresses(Network
*network
) {
677 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
678 if (address
->family
== AF_INET6
)
685 int config_parse_stacked_netdev(const char *unit
,
686 const char *filename
,
689 unsigned section_line
,
695 _cleanup_free_
char *name
= NULL
;
696 NetDevKind kind
= ltype
;
705 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
706 NETDEV_KIND_IPVLAN
, NETDEV_KIND_VXLAN
, NETDEV_KIND_L2TP
,
707 NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
));
709 if (!ifname_valid(rvalue
)) {
710 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
711 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
715 name
= strdup(rvalue
);
719 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
723 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
725 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
726 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
728 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
729 "NetDev '%s' specified twice, ignoring.", name
);
736 int config_parse_domains(
738 const char *filename
,
741 unsigned section_line
,
756 if (isempty(rvalue
)) {
757 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
758 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
764 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
768 r
= extract_first_word(&p
, &w
, NULL
, 0);
770 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
771 "Failed to extract search or route domain, ignoring: %s", rvalue
);
777 is_route
= w
[0] == '~';
778 domain
= is_route
? w
+ 1 : w
;
780 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
781 /* If the root domain appears as is, or the special token "*" is found, we'll
782 * consider this as routing domain, unconditionally. */
784 domain
= "."; /* make sure we don't allow empty strings, thus write the root
787 r
= dns_name_normalize(domain
, 0, &normalized
);
789 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
790 "'%s' is not a valid domain name, ignoring.", domain
);
796 if (is_localhost(domain
)) {
797 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
798 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
804 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
805 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
809 r
= ordered_set_put_strdup(*set
, domain
);
817 int config_parse_ipv4ll(
819 const char *filename
,
822 unsigned section_line
,
829 AddressFamilyBoolean
*link_local
= data
;
837 /* Note that this is mostly like
838 * config_parse_address_family_boolean(), except that it
839 * applies only to IPv4 */
841 r
= parse_boolean(rvalue
);
843 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
844 "Failed to parse %s=%s, ignoring assignment. "
845 "Note that the setting %s= is deprecated, please use LinkLocalAddressing= instead.",
846 lvalue
, rvalue
, lvalue
);
850 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, r
);
852 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
853 "%s=%s is deprecated, please use LinkLocalAddressing=%s instead.",
854 lvalue
, rvalue
, address_family_boolean_to_string(*link_local
));
859 int config_parse_dhcp(
861 const char *filename
,
864 unsigned section_line
,
871 AddressFamilyBoolean
*dhcp
= data
, s
;
878 /* Note that this is mostly like
879 * config_parse_address_family_boolean(), except that it
880 * understands some old names for the enum values */
882 s
= address_family_boolean_from_string(rvalue
);
885 /* Previously, we had a slightly different enum here,
886 * support its values for compatibility. */
888 if (streq(rvalue
, "none"))
889 s
= ADDRESS_FAMILY_NO
;
890 else if (streq(rvalue
, "v4"))
891 s
= ADDRESS_FAMILY_IPV4
;
892 else if (streq(rvalue
, "v6"))
893 s
= ADDRESS_FAMILY_IPV6
;
894 else if (streq(rvalue
, "both"))
895 s
= ADDRESS_FAMILY_YES
;
897 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
898 "Failed to parse DHCP option, ignoring: %s", rvalue
);
902 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
903 "DHCP=%s is deprecated, please use DHCP=%s instead.",
904 rvalue
, address_family_boolean_to_string(s
));
911 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
912 [DHCP_CLIENT_ID_MAC
] = "mac",
913 [DHCP_CLIENT_ID_DUID
] = "duid",
914 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
917 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
918 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
919 "Failed to parse client identifier type");
921 int config_parse_ipv6token(
923 const char *filename
,
926 unsigned section_line
,
933 union in_addr_union buffer
;
934 struct in6_addr
*token
= data
;
942 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
944 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
945 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
949 if (in_addr_is_null(AF_INET6
, &buffer
)) {
950 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
951 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
955 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
956 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
957 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
966 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
967 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
968 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
969 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
972 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
974 int config_parse_ipv6_privacy_extensions(
976 const char *filename
,
979 unsigned section_line
,
986 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
992 assert(ipv6_privacy_extensions
);
994 /* Our enum shall be a superset of booleans, hence first try
995 * to parse as boolean, and then as enum */
997 k
= parse_boolean(rvalue
);
999 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
1001 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
1003 IPv6PrivacyExtensions s
;
1005 s
= ipv6_privacy_extensions_from_string(rvalue
);
1008 if (streq(rvalue
, "kernel"))
1009 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1011 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1012 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1017 *ipv6_privacy_extensions
= s
;
1023 int config_parse_hostname(
1025 const char *filename
,
1027 const char *section
,
1028 unsigned section_line
,
1035 _cleanup_free_
char *hn
= NULL
;
1036 char **hostname
= data
;
1043 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1047 if (!hostname_is_valid(hn
, false)) {
1048 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1049 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1053 r
= dns_name_is_valid(hn
);
1055 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1056 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1060 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1061 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1065 return free_and_replace(*hostname
, hn
);
1068 int config_parse_timezone(
1070 const char *filename
,
1072 const char *section
,
1073 unsigned section_line
,
1080 _cleanup_free_
char *tz
= NULL
;
1081 char **datap
= data
;
1088 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1092 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1093 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1094 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1098 return free_and_replace(*datap
, tz
);
1101 int config_parse_dhcp_server_dns(
1103 const char *filename
,
1105 const char *section
,
1106 unsigned section_line
,
1114 const char *p
= rvalue
;
1122 _cleanup_free_
char *w
= NULL
;
1123 union in_addr_union a
;
1126 r
= extract_first_word(&p
, &w
, NULL
, 0);
1130 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1131 "Failed to extract word, ignoring: %s", rvalue
);
1137 r
= in_addr_from_string(AF_INET
, w
, &a
);
1139 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1140 "Failed to parse DNS server address '%s', ignoring assignment: %m", w
);
1144 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1148 m
[n
->n_dhcp_server_dns
++] = a
.in
;
1149 n
->dhcp_server_dns
= m
;
1155 int config_parse_radv_dns(
1157 const char *filename
,
1159 const char *section
,
1160 unsigned section_line
,
1168 const char *p
= rvalue
;
1176 _cleanup_free_
char *w
= NULL
;
1177 union in_addr_union a
;
1179 r
= extract_first_word(&p
, &w
, NULL
, 0);
1183 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1184 "Failed to extract word, ignoring: %s", rvalue
);
1190 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1193 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1197 m
[n
->n_router_dns
++] = a
.in6
;
1201 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1202 "Failed to parse DNS server address, ignoring: %s", w
);
1208 int config_parse_radv_search_domains(
1210 const char *filename
,
1212 const char *section
,
1213 unsigned section_line
,
1221 const char *p
= rvalue
;
1229 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1231 r
= extract_first_word(&p
, &w
, NULL
, 0);
1235 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1236 "Failed to extract word, ignoring: %s", rvalue
);
1242 r
= dns_name_apply_idna(w
, &idna
);
1244 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1245 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1248 /* transfer ownership to simplify subsequent operations */
1251 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1255 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1263 int config_parse_dhcp_server_ntp(
1265 const char *filename
,
1267 const char *section
,
1268 unsigned section_line
,
1276 const char *p
= rvalue
;
1284 _cleanup_free_
char *w
= NULL
;
1285 union in_addr_union a
;
1288 r
= extract_first_word(&p
, &w
, NULL
, 0);
1292 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1293 "Failed to extract word, ignoring: %s", rvalue
);
1299 r
= in_addr_from_string(AF_INET
, w
, &a
);
1301 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1302 "Failed to parse NTP server address '%s', ignoring: %m", w
);
1306 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1310 m
[n
->n_dhcp_server_ntp
++] = a
.in
;
1311 n
->dhcp_server_ntp
= m
;
1315 int config_parse_dns(
1317 const char *filename
,
1319 const char *section
,
1320 unsigned section_line
,
1327 Network
*n
= userdata
;
1335 _cleanup_free_
char *w
= NULL
;
1336 union in_addr_union a
;
1337 struct in_addr_data
*m
;
1340 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1344 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1345 "Invalid syntax, ignoring: %s", rvalue
);
1351 r
= in_addr_from_string_auto(w
, &family
, &a
);
1353 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1354 "Failed to parse dns server address, ignoring: %s", w
);
1358 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1362 m
[n
->n_dns
++] = (struct in_addr_data
) {
1373 int config_parse_dnssec_negative_trust_anchors(
1375 const char *filename
,
1377 const char *section
,
1378 unsigned section_line
,
1385 const char *p
= rvalue
;
1393 if (isempty(rvalue
)) {
1394 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1399 _cleanup_free_
char *w
= NULL
;
1401 r
= extract_first_word(&p
, &w
, NULL
, 0);
1403 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1404 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1410 r
= dns_name_is_valid(w
);
1412 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1413 "%s is not a valid domain name, ignoring.", w
);
1417 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1421 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1431 int config_parse_ntp(
1433 const char *filename
,
1435 const char *section
,
1436 unsigned section_line
,
1450 if (isempty(rvalue
)) {
1456 _cleanup_free_
char *w
= NULL
;
1458 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1462 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1463 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1469 r
= dns_name_is_valid_or_address(w
);
1471 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1472 "%s is not a valid domain name or IP address, ignoring.", w
);
1476 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1477 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1478 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1479 MAX_NTP_SERVERS
, w
);
1483 r
= strv_consume(l
, TAKE_PTR(w
));
1491 int config_parse_dhcp_user_class(
1493 const char *filename
,
1495 const char *section
,
1496 unsigned section_line
,
1510 if (isempty(rvalue
)) {
1516 _cleanup_free_
char *w
= NULL
;
1518 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1522 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1523 "Failed to split user classes option, ignoring: %s", rvalue
);
1529 if (strlen(w
) > 255) {
1530 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1531 "%s length is not in the range 1-255, ignoring.", w
);
1535 r
= strv_push(l
, w
);
1545 int config_parse_section_route_table(
1547 const char *filename
,
1549 const char *section
,
1550 unsigned section_line
,
1557 Network
*network
= data
;
1566 r
= safe_atou32(rvalue
, &rt
);
1568 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1569 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1573 if (streq_ptr(section
, "DHCP")) {
1574 network
->dhcp_route_table
= rt
;
1575 network
->dhcp_route_table_set
= true;
1576 } else { /* section is IPv6AcceptRA */
1577 network
->ipv6_accept_ra_route_table
= rt
;
1578 network
->ipv6_accept_ra_route_table_set
= true;
1584 int config_parse_dhcp_max_attempts(
1586 const char *filename
,
1588 const char *section
,
1589 unsigned section_line
,
1596 Network
*network
= data
;
1604 if (isempty(rvalue
)) {
1605 network
->dhcp_max_attempts
= 0;
1609 if (streq(rvalue
, "infinity")) {
1610 network
->dhcp_max_attempts
= (uint64_t) -1;
1614 r
= safe_atou64(rvalue
, &a
);
1616 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1617 "Failed to parse DHCP maximum attempts, ignoring: %s", rvalue
);
1622 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1623 "%s= must be positive integer or 'infinity', ignoring: %s", lvalue
, rvalue
);
1627 network
->dhcp_max_attempts
= a
;
1632 int config_parse_dhcp_black_listed_ip_address(
1634 const char *filename
,
1636 const char *section
,
1637 unsigned section_line
,
1644 Network
*network
= data
;
1653 if (isempty(rvalue
)) {
1654 network
->dhcp_black_listed_ip
= set_free(network
->dhcp_black_listed_ip
);
1658 for (p
= rvalue
;;) {
1659 _cleanup_free_
char *n
= NULL
;
1660 union in_addr_union ip
;
1662 r
= extract_first_word(&p
, &n
, NULL
, 0);
1664 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1665 "Failed to parse DHCP black listed ip address, ignoring assignment: %s",
1672 r
= in_addr_from_string(AF_INET
, n
, &ip
);
1674 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1675 "DHCP black listed ip address is invalid, ignoring assignment: %s", n
);
1679 r
= set_ensure_allocated(&network
->dhcp_black_listed_ip
, NULL
);
1683 r
= set_put(network
->dhcp_black_listed_ip
, UINT32_TO_PTR(ip
.in
.s_addr
));
1685 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1686 "DHCP black listed ip address is duplicated, ignoring assignment: %s", n
);
1690 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1691 "Failed to store DHCP black listed ip address '%s', ignoring assignment: %m", n
);
1697 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1698 "Failed to parse DHCP use domains setting");
1700 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1701 [DHCP_USE_DOMAINS_NO
] = "no",
1702 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1703 [DHCP_USE_DOMAINS_YES
] = "yes",
1706 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1708 int config_parse_iaid(const char *unit
,
1709 const char *filename
,
1711 const char *section
,
1712 unsigned section_line
,
1718 Network
*network
= data
;
1727 r
= safe_atou32(rvalue
, &iaid
);
1729 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1730 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1734 network
->iaid
= iaid
;
1735 network
->iaid_set
= true;
1740 int config_parse_required_for_online(
1742 const char *filename
,
1744 const char *section
,
1745 unsigned section_line
,
1752 Network
*network
= data
;
1753 LinkOperationalState s
;
1754 bool required
= true;
1757 if (isempty(rvalue
)) {
1758 network
->required_for_online
= true;
1759 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1763 s
= link_operstate_from_string(rvalue
);
1765 r
= parse_boolean(rvalue
);
1767 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1768 "Failed to parse %s= setting, ignoring assignment: %s",
1774 s
= LINK_OPERSTATE_DEGRADED
;
1777 network
->required_for_online
= required
;
1778 network
->required_operstate_for_online
= s
;