1 /* SPDX-License-Identifier: LGPL-2.1+ */
6 #include "alloc-util.h"
7 #include "conf-files.h"
8 #include "conf-parser.h"
9 #include "dns-domain.h"
11 #include "hostname-util.h"
12 #include "in-addr-util.h"
13 #include "missing_network.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
,
107 NETDEV_KIND_IP6TNL
)))
108 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
109 "%s: NetDev %s is not a %s, ignoring assignment",
110 network
->filename
, name
, kind_string
);
112 *ret_netdev
= netdev_ref(netdev
);
116 static int network_resolve_stacked_netdevs(Network
*network
) {
123 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
124 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
126 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
130 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
134 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
136 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
137 network
->filename
, (const char *) name
);
145 static uint32_t network_get_stacked_netdevs_mtu(Network
*network
) {
150 HASHMAP_FOREACH(dev
, network
->stacked_netdevs
, i
)
151 if (dev
->kind
== NETDEV_KIND_VLAN
&& dev
->mtu
> 0)
152 /* See vlan_dev_change_mtu() in kernel.
153 * Note that the additional 4bytes may not be necessary for all devices. */
154 mtu
= MAX(mtu
, dev
->mtu
+ 4);
156 else if (dev
->kind
== NETDEV_KIND_MACVLAN
&& dev
->mtu
> mtu
)
157 /* See macvlan_change_mtu() in kernel. */
163 int network_verify(Network
*network
) {
164 Address
*address
, *address_next
;
165 Route
*route
, *route_next
;
166 FdbEntry
*fdb
, *fdb_next
;
167 Neighbor
*neighbor
, *neighbor_next
;
168 AddressLabel
*label
, *label_next
;
169 Prefix
*prefix
, *prefix_next
;
170 RoutingPolicyRule
*rule
, *rule_next
;
174 assert(network
->filename
);
176 /* skip out early if configuration does not match the environment */
177 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
178 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
179 "%s: Conditions in the file do not match the system environment, skipping.",
182 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
183 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
184 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
185 (void) network_resolve_stacked_netdevs(network
);
187 /* Free unnecessary entries. */
188 network
->bond_name
= mfree(network
->bond_name
);
189 network
->bridge_name
= mfree(network
->bridge_name
);
190 network
->vrf_name
= mfree(network
->vrf_name
);
191 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
194 /* Bonding slave does not support addressing. */
195 if (network
->ipv6_accept_ra
> 0) {
196 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
198 network
->ipv6_accept_ra
= 0;
200 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
201 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
203 network
->link_local
= ADDRESS_FAMILY_NO
;
205 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
206 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
208 network
->dhcp
= ADDRESS_FAMILY_NO
;
210 if (network
->dhcp_server
) {
211 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
213 network
->dhcp_server
= false;
215 if (network
->n_static_addresses
> 0) {
216 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
218 while ((address
= network
->static_addresses
))
219 address_free(address
);
221 if (network
->n_static_routes
> 0) {
222 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
224 while ((route
= network
->static_routes
))
229 if (network
->link_local
< 0)
230 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
232 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
233 network
->ipv6_accept_ra
= false;
235 /* IPMasquerade=yes implies IPForward=yes */
236 if (network
->ip_masquerade
)
237 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
239 network
->mtu_is_set
= network
->mtu
> 0;
240 mtu
= network_get_stacked_netdevs_mtu(network
);
241 if (network
->mtu
< mtu
) {
242 if (network
->mtu_is_set
)
243 log_notice("%s: Bumping MTUBytes= from %"PRIu32
" to %"PRIu32
" because of stacked device",
244 network
->filename
, network
->mtu
, mtu
);
248 if (network
->mtu_is_set
&& network
->dhcp_use_mtu
) {
249 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
250 "Disabling UseMTU=.", network
->filename
);
251 network
->dhcp_use_mtu
= false;
254 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
255 if (address_section_verify(address
) < 0)
256 address_free(address
);
258 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
259 if (route_section_verify(route
, network
) < 0)
262 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
263 if (section_is_invalid(fdb
->section
))
266 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
267 if (section_is_invalid(neighbor
->section
))
268 neighbor_free(neighbor
);
270 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
271 if (section_is_invalid(label
->section
))
272 address_label_free(label
);
274 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
275 if (section_is_invalid(prefix
->section
))
278 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
279 if (section_is_invalid(rule
->section
))
280 routing_policy_rule_free(rule
);
285 int network_load_one(Manager
*manager
, const char *filename
) {
286 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
287 _cleanup_(network_freep
) Network
*network
= NULL
;
288 _cleanup_fclose_
FILE *file
= NULL
;
289 const char *dropin_dirname
;
296 file
= fopen(filename
, "re");
304 if (null_or_empty_fd(fileno(file
))) {
305 log_debug("Skipping empty file: %s", filename
);
309 fname
= strdup(filename
);
313 name
= strdup(basename(filename
));
317 d
= strrchr(name
, '.');
323 dropin_dirname
= strjoina(name
, ".network.d");
325 network
= new(Network
, 1);
329 *network
= (Network
) {
330 .filename
= TAKE_PTR(fname
),
331 .name
= TAKE_PTR(name
),
333 .required_for_online
= true,
334 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
335 .dhcp
= ADDRESS_FAMILY_NO
,
336 .dhcp_use_ntp
= true,
337 .dhcp_use_dns
= true,
338 .dhcp_use_hostname
= true,
339 .dhcp_use_routes
= true,
340 /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
341 .dhcp_send_hostname
= true,
342 /* To enable/disable RFC7844 Anonymity Profiles */
343 .dhcp_anonymize
= false,
344 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
345 /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
346 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
347 .dhcp_route_table
= RT_TABLE_MAIN
,
348 .dhcp_route_table_set
= false,
349 /* NOTE: from man: UseMTU=... Defaults to false*/
350 .dhcp_use_mtu
= false,
351 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
352 .dhcp_use_timezone
= false,
353 .rapid_commit
= true,
355 .dhcp_server_emit_dns
= true,
356 .dhcp_server_emit_ntp
= true,
357 .dhcp_server_emit_router
= true,
358 .dhcp_server_emit_timezone
= true,
360 .router_emit_dns
= true,
361 .router_emit_domains
= true,
366 .allow_port_to_be_root
= -1,
368 .multicast_flood
= -1,
369 .multicast_to_unicast
= -1,
370 .neighbor_suppression
= -1,
372 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
374 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
376 .dns_default_route
= -1,
377 .llmnr
= RESOLVE_SUPPORT_YES
,
378 .mdns
= RESOLVE_SUPPORT_NO
,
379 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
380 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
382 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
383 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
385 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
386 .ipv6_accept_ra
= -1,
387 .ipv6_dad_transmits
= -1,
388 .ipv6_hop_limit
= -1,
389 .ipv6_proxy_ndp
= -1,
390 .duid
.type
= _DUID_TYPE_INVALID
,
395 .ipv6_accept_ra_use_dns
= true,
396 .ipv6_accept_ra_use_autonomous_prefix
= true,
397 .ipv6_accept_ra_use_onlink_prefix
= true,
398 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
399 .ipv6_accept_ra_route_table_set
= false,
401 .can_triple_sampling
= -1,
404 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
411 "RoutingPolicyRule\0"
414 "DHCPv4\0" /* compat */
417 "IPv6NDPProxyAddress\0"
421 "IPv6PrefixDelegation\0"
424 config_item_perf_lookup
, network_network_gperf_lookup
,
425 CONFIG_PARSE_WARN
, network
);
429 network_apply_anonymize_if_set(network
);
431 r
= network_add_ipv4ll_route(network
);
433 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
435 LIST_PREPEND(networks
, manager
->networks
, network
);
436 network
->manager
= manager
;
438 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
442 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
446 if (network_verify(network
) < 0)
453 int network_load(Manager
*manager
) {
455 _cleanup_strv_free_
char **files
= NULL
;
461 while ((network
= manager
->networks
))
462 network_free(network
);
464 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
466 return log_error_errno(r
, "Failed to enumerate network files: %m");
468 STRV_FOREACH_BACKWARDS(f
, files
) {
469 r
= network_load_one(manager
, *f
);
477 void network_free(Network
*network
) {
478 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
479 RoutingPolicyRule
*rule
;
490 free(network
->filename
);
492 set_free_free(network
->match_mac
);
493 strv_free(network
->match_path
);
494 strv_free(network
->match_driver
);
495 strv_free(network
->match_type
);
496 strv_free(network
->match_name
);
497 condition_free_list(network
->conditions
);
499 free(network
->description
);
500 free(network
->dhcp_vendor_class_identifier
);
501 strv_free(network
->dhcp_user_class
);
502 free(network
->dhcp_hostname
);
506 strv_free(network
->ntp
);
508 ordered_set_free_free(network
->search_domains
);
509 ordered_set_free_free(network
->route_domains
);
510 strv_free(network
->bind_carrier
);
512 ordered_set_free_free(network
->router_search_domains
);
513 free(network
->router_dns
);
515 free(network
->bridge_name
);
516 free(network
->bond_name
);
517 free(network
->vrf_name
);
518 hashmap_free_free_key(network
->stacked_netdev_names
);
519 netdev_unref(network
->bridge
);
520 netdev_unref(network
->bond
);
521 netdev_unref(network
->vrf
);
522 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
524 while ((route
= network
->static_routes
))
527 while ((address
= network
->static_addresses
))
528 address_free(address
);
530 while ((fdb_entry
= network
->static_fdb_entries
))
531 fdb_entry_free(fdb_entry
);
533 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
534 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
536 while ((neighbor
= network
->neighbors
))
537 neighbor_free(neighbor
);
539 while ((label
= network
->address_labels
))
540 address_label_free(label
);
542 while ((prefix
= network
->static_prefixes
))
545 while ((rule
= network
->rules
))
546 routing_policy_rule_free(rule
);
548 hashmap_free(network
->addresses_by_section
);
549 hashmap_free(network
->routes_by_section
);
550 hashmap_free(network
->fdb_entries_by_section
);
551 hashmap_free(network
->neighbors_by_section
);
552 hashmap_free(network
->address_labels_by_section
);
553 hashmap_free(network
->prefixes_by_section
);
554 hashmap_free(network
->rules_by_section
);
556 if (network
->manager
) {
557 if (network
->manager
->networks
)
558 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
560 if (network
->manager
->networks_by_name
&& network
->name
)
561 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
563 if (network
->manager
->duids_requesting_uuid
)
564 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
569 free(network
->dhcp_server_timezone
);
570 free(network
->dhcp_server_dns
);
571 free(network
->dhcp_server_ntp
);
573 set_free_free(network
->dnssec_negative_trust_anchors
);
578 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
585 network
= hashmap_get(manager
->networks_by_name
, name
);
594 int network_get(Manager
*manager
, sd_device
*device
,
595 const char *ifname
, const struct ether_addr
*address
,
597 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
604 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
606 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
608 (void) sd_device_get_devtype(device
, &devtype
);
611 LIST_FOREACH(networks
, network
, manager
->networks
) {
612 if (net_match_config(network
->match_mac
, network
->match_path
,
613 network
->match_driver
, network
->match_type
,
615 address
, path
, driver
, devtype
, ifname
)) {
616 if (network
->match_name
&& device
) {
618 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
620 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
621 (void) safe_atou8(attr
, &name_assign_type
);
623 if (name_assign_type
== NET_NAME_ENUM
)
624 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
625 ifname
, network
->filename
);
627 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
629 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
641 int network_apply(Network
*network
, Link
*link
) {
645 link
->network
= network
;
647 if (network
->n_dns
> 0 ||
648 !strv_isempty(network
->ntp
) ||
649 !ordered_set_isempty(network
->search_domains
) ||
650 !ordered_set_isempty(network
->route_domains
))
656 bool network_has_static_ipv6_addresses(Network
*network
) {
661 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
662 if (address
->family
== AF_INET6
)
669 int config_parse_stacked_netdev(const char *unit
,
670 const char *filename
,
673 unsigned section_line
,
679 _cleanup_free_
char *name
= NULL
;
680 NetDevKind kind
= ltype
;
689 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
690 NETDEV_KIND_IPVLAN
, NETDEV_KIND_VXLAN
, NETDEV_KIND_L2TP
,
691 _NETDEV_KIND_TUNNEL
));
693 if (!ifname_valid(rvalue
)) {
694 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
695 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
699 name
= strdup(rvalue
);
703 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
707 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
709 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
710 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
712 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
713 "NetDev '%s' specified twice, ignoring.", name
);
720 int config_parse_domains(
722 const char *filename
,
725 unsigned section_line
,
740 if (isempty(rvalue
)) {
741 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
742 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
748 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
752 r
= extract_first_word(&p
, &w
, NULL
, 0);
754 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
755 "Failed to extract search or route domain, ignoring: %s", rvalue
);
761 is_route
= w
[0] == '~';
762 domain
= is_route
? w
+ 1 : w
;
764 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
765 /* If the root domain appears as is, or the special token "*" is found, we'll
766 * consider this as routing domain, unconditionally. */
768 domain
= "."; /* make sure we don't allow empty strings, thus write the root
771 r
= dns_name_normalize(domain
, 0, &normalized
);
773 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
774 "'%s' is not a valid domain name, ignoring.", domain
);
780 if (is_localhost(domain
)) {
781 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
782 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
788 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
789 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
793 r
= ordered_set_put_strdup(*set
, domain
);
801 int config_parse_ipv4ll(
803 const char *filename
,
806 unsigned section_line
,
813 AddressFamilyBoolean
*link_local
= data
;
820 /* Note that this is mostly like
821 * config_parse_address_family_boolean(), except that it
822 * applies only to IPv4 */
824 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, parse_boolean(rvalue
));
829 int config_parse_dhcp(
831 const char *filename
,
834 unsigned section_line
,
841 AddressFamilyBoolean
*dhcp
= data
, s
;
848 /* Note that this is mostly like
849 * config_parse_address_family_boolean(), except that it
850 * understands some old names for the enum values */
852 s
= address_family_boolean_from_string(rvalue
);
855 /* Previously, we had a slightly different enum here,
856 * support its values for compatbility. */
858 if (streq(rvalue
, "none"))
859 s
= ADDRESS_FAMILY_NO
;
860 else if (streq(rvalue
, "v4"))
861 s
= ADDRESS_FAMILY_IPV4
;
862 else if (streq(rvalue
, "v6"))
863 s
= ADDRESS_FAMILY_IPV6
;
864 else if (streq(rvalue
, "both"))
865 s
= ADDRESS_FAMILY_YES
;
867 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
868 "Failed to parse DHCP option, ignoring: %s", rvalue
);
872 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
873 "DHCP=%s is deprecated, please use DHCP=%s instead.",
874 rvalue
, address_family_boolean_to_string(s
));
881 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
882 [DHCP_CLIENT_ID_MAC
] = "mac",
883 [DHCP_CLIENT_ID_DUID
] = "duid",
884 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
887 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
888 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
889 "Failed to parse client identifier type");
891 int config_parse_ipv6token(
893 const char *filename
,
896 unsigned section_line
,
903 union in_addr_union buffer
;
904 struct in6_addr
*token
= data
;
912 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
914 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
915 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
919 if (in_addr_is_null(AF_INET6
, &buffer
)) {
920 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
921 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
925 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
926 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
927 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
936 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
937 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
938 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
939 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
942 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
944 int config_parse_ipv6_privacy_extensions(
946 const char *filename
,
949 unsigned section_line
,
956 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
962 assert(ipv6_privacy_extensions
);
964 /* Our enum shall be a superset of booleans, hence first try
965 * to parse as boolean, and then as enum */
967 k
= parse_boolean(rvalue
);
969 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
971 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
973 IPv6PrivacyExtensions s
;
975 s
= ipv6_privacy_extensions_from_string(rvalue
);
978 if (streq(rvalue
, "kernel"))
979 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
981 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
982 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
987 *ipv6_privacy_extensions
= s
;
993 int config_parse_hostname(
995 const char *filename
,
998 unsigned section_line
,
1005 _cleanup_free_
char *hn
= NULL
;
1006 char **hostname
= data
;
1013 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1017 if (!hostname_is_valid(hn
, false)) {
1018 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1019 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1023 r
= dns_name_is_valid(hn
);
1025 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1026 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1030 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1031 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1035 return free_and_replace(*hostname
, hn
);
1038 int config_parse_timezone(
1040 const char *filename
,
1042 const char *section
,
1043 unsigned section_line
,
1050 _cleanup_free_
char *tz
= NULL
;
1051 char **datap
= data
;
1058 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1062 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1063 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1064 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1068 return free_and_replace(*datap
, tz
);
1071 int config_parse_dhcp_server_dns(
1073 const char *filename
,
1075 const char *section
,
1076 unsigned section_line
,
1084 const char *p
= rvalue
;
1092 _cleanup_free_
char *w
= NULL
;
1093 struct in_addr a
, *m
;
1095 r
= extract_first_word(&p
, &w
, NULL
, 0);
1099 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1100 "Failed to extract word, ignoring: %s", rvalue
);
1106 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1107 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1108 "Failed to parse DNS server address, ignoring: %s", w
);
1112 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1116 m
[n
->n_dhcp_server_dns
++] = a
;
1117 n
->dhcp_server_dns
= m
;
1123 int config_parse_radv_dns(
1125 const char *filename
,
1127 const char *section
,
1128 unsigned section_line
,
1136 const char *p
= rvalue
;
1144 _cleanup_free_
char *w
= NULL
;
1145 union in_addr_union a
;
1147 r
= extract_first_word(&p
, &w
, NULL
, 0);
1151 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1152 "Failed to extract word, ignoring: %s", rvalue
);
1158 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1161 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1165 m
[n
->n_router_dns
++] = a
.in6
;
1169 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1170 "Failed to parse DNS server address, ignoring: %s", w
);
1176 int config_parse_radv_search_domains(
1178 const char *filename
,
1180 const char *section
,
1181 unsigned section_line
,
1189 const char *p
= rvalue
;
1197 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1199 r
= extract_first_word(&p
, &w
, NULL
, 0);
1203 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1204 "Failed to extract word, ignoring: %s", rvalue
);
1210 r
= dns_name_apply_idna(w
, &idna
);
1212 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1213 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1216 /* transfer ownership to simplify subsequent operations */
1219 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1223 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1231 int config_parse_dhcp_server_ntp(
1233 const char *filename
,
1235 const char *section
,
1236 unsigned section_line
,
1244 const char *p
= rvalue
;
1252 _cleanup_free_
char *w
= NULL
;
1253 struct in_addr a
, *m
;
1255 r
= extract_first_word(&p
, &w
, NULL
, 0);
1259 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1260 "Failed to extract word, ignoring: %s", rvalue
);
1266 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1267 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1268 "Failed to parse NTP server address, ignoring: %s", w
);
1272 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1276 m
[n
->n_dhcp_server_ntp
++] = a
;
1277 n
->dhcp_server_ntp
= m
;
1281 int config_parse_dns(
1283 const char *filename
,
1285 const char *section
,
1286 unsigned section_line
,
1293 Network
*n
= userdata
;
1301 _cleanup_free_
char *w
= NULL
;
1302 union in_addr_union a
;
1303 struct in_addr_data
*m
;
1306 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1310 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1311 "Invalid syntax, ignoring: %s", rvalue
);
1317 r
= in_addr_from_string_auto(w
, &family
, &a
);
1319 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1320 "Failed to parse dns server address, ignoring: %s", w
);
1324 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1328 m
[n
->n_dns
++] = (struct in_addr_data
) {
1339 int config_parse_dnssec_negative_trust_anchors(
1341 const char *filename
,
1343 const char *section
,
1344 unsigned section_line
,
1351 const char *p
= rvalue
;
1359 if (isempty(rvalue
)) {
1360 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1365 _cleanup_free_
char *w
= NULL
;
1367 r
= extract_first_word(&p
, &w
, NULL
, 0);
1369 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1370 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1376 r
= dns_name_is_valid(w
);
1378 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1379 "%s is not a valid domain name, ignoring.", w
);
1383 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1387 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1397 int config_parse_ntp(
1399 const char *filename
,
1401 const char *section
,
1402 unsigned section_line
,
1416 if (isempty(rvalue
)) {
1422 _cleanup_free_
char *w
= NULL
;
1424 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1428 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1429 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1435 r
= dns_name_is_valid_or_address(w
);
1437 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1438 "%s is not a valid domain name or IP address, ignoring.", w
);
1442 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1443 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1444 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1445 MAX_NTP_SERVERS
, w
);
1449 r
= strv_consume(l
, TAKE_PTR(w
));
1457 int config_parse_dhcp_user_class(
1459 const char *filename
,
1461 const char *section
,
1462 unsigned section_line
,
1476 if (isempty(rvalue
)) {
1482 _cleanup_free_
char *w
= NULL
;
1484 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1488 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1489 "Failed to split user classes option, ignoring: %s", rvalue
);
1495 if (strlen(w
) > 255) {
1496 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1497 "%s length is not in the range 1-255, ignoring.", w
);
1501 r
= strv_push(l
, w
);
1511 int config_parse_section_route_table(
1513 const char *filename
,
1515 const char *section
,
1516 unsigned section_line
,
1523 Network
*network
= data
;
1532 r
= safe_atou32(rvalue
, &rt
);
1534 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1535 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1539 if (streq_ptr(section
, "DHCP")) {
1540 network
->dhcp_route_table
= rt
;
1541 network
->dhcp_route_table_set
= true;
1542 } else { /* section is IPv6AcceptRA */
1543 network
->ipv6_accept_ra_route_table
= rt
;
1544 network
->ipv6_accept_ra_route_table_set
= true;
1550 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1551 "Failed to parse DHCP use domains setting");
1553 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1554 [DHCP_USE_DOMAINS_NO
] = "no",
1555 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1556 [DHCP_USE_DOMAINS_YES
] = "yes",
1559 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1561 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1563 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1564 [LLDP_MODE_NO
] = "no",
1565 [LLDP_MODE_YES
] = "yes",
1566 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1569 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
1571 int config_parse_iaid(const char *unit
,
1572 const char *filename
,
1574 const char *section
,
1575 unsigned section_line
,
1581 Network
*network
= data
;
1590 r
= safe_atou32(rvalue
, &iaid
);
1592 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1593 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1597 network
->iaid
= iaid
;
1598 network
->iaid_set
= true;
1603 int config_parse_required_for_online(
1605 const char *filename
,
1607 const char *section
,
1608 unsigned section_line
,
1615 Network
*network
= data
;
1616 LinkOperationalState s
;
1617 bool required
= true;
1620 if (isempty(rvalue
)) {
1621 network
->required_for_online
= true;
1622 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1626 s
= link_operstate_from_string(rvalue
);
1628 r
= parse_boolean(rvalue
);
1630 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1631 "Failed to parse %s= setting, ignoring assignment: %s",
1637 s
= LINK_OPERSTATE_DEGRADED
;
1640 network
->required_for_online
= required
;
1641 network
->required_operstate_for_online
= s
;