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
,
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 /* skip out early if configuration does not match the environment */
178 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
179 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
180 "%s: Conditions in the file do not match the system environment, skipping.",
183 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
184 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
185 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
186 (void) network_resolve_stacked_netdevs(network
);
188 /* Free unnecessary entries. */
189 network
->bond_name
= mfree(network
->bond_name
);
190 network
->bridge_name
= mfree(network
->bridge_name
);
191 network
->vrf_name
= mfree(network
->vrf_name
);
192 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
195 /* Bonding slave does not support addressing. */
196 if (network
->ipv6_accept_ra
> 0) {
197 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
199 network
->ipv6_accept_ra
= 0;
201 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
202 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
204 network
->link_local
= ADDRESS_FAMILY_NO
;
206 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
207 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
209 network
->dhcp
= ADDRESS_FAMILY_NO
;
211 if (network
->dhcp_server
) {
212 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
214 network
->dhcp_server
= false;
216 if (network
->n_static_addresses
> 0) {
217 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
219 while ((address
= network
->static_addresses
))
220 address_free(address
);
222 if (network
->n_static_routes
> 0) {
223 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
225 while ((route
= network
->static_routes
))
230 if (network
->link_local
< 0)
231 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
233 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
234 network
->ipv6_accept_ra
= false;
236 /* IPMasquerade=yes implies IPForward=yes */
237 if (network
->ip_masquerade
)
238 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
240 network
->mtu_is_set
= network
->mtu
> 0;
241 mtu
= network_get_stacked_netdevs_mtu(network
);
242 if (network
->mtu
< mtu
) {
243 if (network
->mtu_is_set
)
244 log_notice("%s: Bumping MTUBytes= from %"PRIu32
" to %"PRIu32
" because of stacked device",
245 network
->filename
, network
->mtu
, mtu
);
249 if (network
->mtu_is_set
&& network
->dhcp_use_mtu
) {
250 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
251 "Disabling UseMTU=.", network
->filename
);
252 network
->dhcp_use_mtu
= false;
255 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
256 if (address_section_verify(address
) < 0)
257 address_free(address
);
259 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
260 if (route_section_verify(route
, network
) < 0)
263 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
264 if (section_is_invalid(fdb
->section
))
267 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
268 if (section_is_invalid(neighbor
->section
))
269 neighbor_free(neighbor
);
271 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
272 if (section_is_invalid(label
->section
))
273 address_label_free(label
);
275 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
276 if (section_is_invalid(prefix
->section
))
279 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
280 if (section_is_invalid(rule
->section
))
281 routing_policy_rule_free(rule
);
286 int network_load_one(Manager
*manager
, const char *filename
) {
287 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
288 _cleanup_(network_freep
) Network
*network
= NULL
;
289 _cleanup_fclose_
FILE *file
= NULL
;
290 const char *dropin_dirname
;
297 file
= fopen(filename
, "re");
305 if (null_or_empty_fd(fileno(file
))) {
306 log_debug("Skipping empty file: %s", filename
);
310 fname
= strdup(filename
);
314 name
= strdup(basename(filename
));
318 d
= strrchr(name
, '.');
324 dropin_dirname
= strjoina(name
, ".network.d");
326 network
= new(Network
, 1);
330 *network
= (Network
) {
331 .filename
= TAKE_PTR(fname
),
332 .name
= TAKE_PTR(name
),
334 .required_for_online
= true,
335 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
336 .dhcp
= ADDRESS_FAMILY_NO
,
337 .dhcp_use_ntp
= true,
338 .dhcp_use_dns
= true,
339 .dhcp_use_hostname
= true,
340 .dhcp_use_routes
= true,
341 /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
342 .dhcp_send_hostname
= true,
343 /* To enable/disable RFC7844 Anonymity Profiles */
344 .dhcp_anonymize
= false,
345 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
346 /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
347 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
348 .dhcp_route_table
= RT_TABLE_MAIN
,
349 .dhcp_route_table_set
= false,
350 /* NOTE: from man: UseMTU=... Defaults to false*/
351 .dhcp_use_mtu
= false,
352 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
353 .dhcp_use_timezone
= false,
354 .rapid_commit
= true,
356 .dhcp_server_emit_dns
= true,
357 .dhcp_server_emit_ntp
= true,
358 .dhcp_server_emit_router
= true,
359 .dhcp_server_emit_timezone
= true,
361 .router_emit_dns
= true,
362 .router_emit_domains
= true,
367 .allow_port_to_be_root
= -1,
369 .multicast_flood
= -1,
370 .multicast_to_unicast
= -1,
371 .neighbor_suppression
= -1,
373 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
375 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
377 .dns_default_route
= -1,
378 .llmnr
= RESOLVE_SUPPORT_YES
,
379 .mdns
= RESOLVE_SUPPORT_NO
,
380 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
381 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
383 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
384 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
386 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
387 .ipv6_accept_ra
= -1,
388 .ipv6_dad_transmits
= -1,
389 .ipv6_hop_limit
= -1,
390 .ipv6_proxy_ndp
= -1,
391 .duid
.type
= _DUID_TYPE_INVALID
,
396 .ipv6_accept_ra_use_dns
= true,
397 .ipv6_accept_ra_use_autonomous_prefix
= true,
398 .ipv6_accept_ra_use_onlink_prefix
= true,
399 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
400 .ipv6_accept_ra_route_table_set
= false,
402 .can_triple_sampling
= -1,
405 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
412 "RoutingPolicyRule\0"
415 "DHCPv4\0" /* compat */
418 "IPv6NDPProxyAddress\0"
422 "IPv6PrefixDelegation\0"
425 config_item_perf_lookup
, network_network_gperf_lookup
,
426 CONFIG_PARSE_WARN
, network
);
430 network_apply_anonymize_if_set(network
);
432 r
= network_add_ipv4ll_route(network
);
434 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
436 LIST_PREPEND(networks
, manager
->networks
, network
);
437 network
->manager
= manager
;
439 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
443 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
447 if (network_verify(network
) < 0)
454 int network_load(Manager
*manager
) {
456 _cleanup_strv_free_
char **files
= NULL
;
462 while ((network
= manager
->networks
))
463 network_free(network
);
465 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
467 return log_error_errno(r
, "Failed to enumerate network files: %m");
469 STRV_FOREACH_BACKWARDS(f
, files
) {
470 r
= network_load_one(manager
, *f
);
478 void network_free(Network
*network
) {
479 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
480 RoutingPolicyRule
*rule
;
491 free(network
->filename
);
493 set_free_free(network
->match_mac
);
494 strv_free(network
->match_path
);
495 strv_free(network
->match_driver
);
496 strv_free(network
->match_type
);
497 strv_free(network
->match_name
);
498 condition_free_list(network
->conditions
);
500 free(network
->description
);
501 free(network
->dhcp_vendor_class_identifier
);
502 strv_free(network
->dhcp_user_class
);
503 free(network
->dhcp_hostname
);
507 strv_free(network
->ntp
);
509 ordered_set_free_free(network
->search_domains
);
510 ordered_set_free_free(network
->route_domains
);
511 strv_free(network
->bind_carrier
);
513 ordered_set_free_free(network
->router_search_domains
);
514 free(network
->router_dns
);
516 free(network
->bridge_name
);
517 free(network
->bond_name
);
518 free(network
->vrf_name
);
519 hashmap_free_free_key(network
->stacked_netdev_names
);
520 netdev_unref(network
->bridge
);
521 netdev_unref(network
->bond
);
522 netdev_unref(network
->vrf
);
523 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
525 while ((route
= network
->static_routes
))
528 while ((address
= network
->static_addresses
))
529 address_free(address
);
531 while ((fdb_entry
= network
->static_fdb_entries
))
532 fdb_entry_free(fdb_entry
);
534 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
535 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
537 while ((neighbor
= network
->neighbors
))
538 neighbor_free(neighbor
);
540 while ((label
= network
->address_labels
))
541 address_label_free(label
);
543 while ((prefix
= network
->static_prefixes
))
546 while ((rule
= network
->rules
))
547 routing_policy_rule_free(rule
);
549 hashmap_free(network
->addresses_by_section
);
550 hashmap_free(network
->routes_by_section
);
551 hashmap_free(network
->fdb_entries_by_section
);
552 hashmap_free(network
->neighbors_by_section
);
553 hashmap_free(network
->address_labels_by_section
);
554 hashmap_free(network
->prefixes_by_section
);
555 hashmap_free(network
->rules_by_section
);
557 if (network
->manager
) {
558 if (network
->manager
->networks
)
559 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
561 if (network
->manager
->networks_by_name
&& network
->name
)
562 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
564 if (network
->manager
->duids_requesting_uuid
)
565 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
570 free(network
->dhcp_server_timezone
);
571 free(network
->dhcp_server_dns
);
572 free(network
->dhcp_server_ntp
);
574 set_free_free(network
->dnssec_negative_trust_anchors
);
579 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
586 network
= hashmap_get(manager
->networks_by_name
, name
);
595 int network_get(Manager
*manager
, sd_device
*device
,
596 const char *ifname
, const struct ether_addr
*address
,
598 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
605 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
607 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
609 (void) sd_device_get_devtype(device
, &devtype
);
612 LIST_FOREACH(networks
, network
, manager
->networks
) {
613 if (net_match_config(network
->match_mac
, network
->match_path
,
614 network
->match_driver
, network
->match_type
,
616 address
, path
, driver
, devtype
, ifname
)) {
617 if (network
->match_name
&& device
) {
619 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
621 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
622 (void) safe_atou8(attr
, &name_assign_type
);
624 if (name_assign_type
== NET_NAME_ENUM
)
625 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
626 ifname
, network
->filename
);
628 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
630 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
642 int network_apply(Network
*network
, Link
*link
) {
646 link
->network
= network
;
648 if (network
->n_dns
> 0 ||
649 !strv_isempty(network
->ntp
) ||
650 !ordered_set_isempty(network
->search_domains
) ||
651 !ordered_set_isempty(network
->route_domains
))
657 bool network_has_static_ipv6_addresses(Network
*network
) {
662 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
663 if (address
->family
== AF_INET6
)
670 int config_parse_stacked_netdev(const char *unit
,
671 const char *filename
,
674 unsigned section_line
,
680 _cleanup_free_
char *name
= NULL
;
681 NetDevKind kind
= ltype
;
690 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
691 NETDEV_KIND_IPVLAN
, NETDEV_KIND_VXLAN
, NETDEV_KIND_L2TP
,
692 _NETDEV_KIND_TUNNEL
));
694 if (!ifname_valid(rvalue
)) {
695 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
696 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
700 name
= strdup(rvalue
);
704 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
708 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
710 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
711 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
713 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
714 "NetDev '%s' specified twice, ignoring.", name
);
721 int config_parse_domains(
723 const char *filename
,
726 unsigned section_line
,
741 if (isempty(rvalue
)) {
742 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
743 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
749 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
753 r
= extract_first_word(&p
, &w
, NULL
, 0);
755 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
756 "Failed to extract search or route domain, ignoring: %s", rvalue
);
762 is_route
= w
[0] == '~';
763 domain
= is_route
? w
+ 1 : w
;
765 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
766 /* If the root domain appears as is, or the special token "*" is found, we'll
767 * consider this as routing domain, unconditionally. */
769 domain
= "."; /* make sure we don't allow empty strings, thus write the root
772 r
= dns_name_normalize(domain
, 0, &normalized
);
774 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
775 "'%s' is not a valid domain name, ignoring.", domain
);
781 if (is_localhost(domain
)) {
782 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
783 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
789 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
790 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
794 r
= ordered_set_put_strdup(*set
, domain
);
802 int config_parse_ipv4ll(
804 const char *filename
,
807 unsigned section_line
,
814 AddressFamilyBoolean
*link_local
= data
;
821 /* Note that this is mostly like
822 * config_parse_address_family_boolean(), except that it
823 * applies only to IPv4 */
825 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, parse_boolean(rvalue
));
830 int config_parse_dhcp(
832 const char *filename
,
835 unsigned section_line
,
842 AddressFamilyBoolean
*dhcp
= data
, s
;
849 /* Note that this is mostly like
850 * config_parse_address_family_boolean(), except that it
851 * understands some old names for the enum values */
853 s
= address_family_boolean_from_string(rvalue
);
856 /* Previously, we had a slightly different enum here,
857 * support its values for compatbility. */
859 if (streq(rvalue
, "none"))
860 s
= ADDRESS_FAMILY_NO
;
861 else if (streq(rvalue
, "v4"))
862 s
= ADDRESS_FAMILY_IPV4
;
863 else if (streq(rvalue
, "v6"))
864 s
= ADDRESS_FAMILY_IPV6
;
865 else if (streq(rvalue
, "both"))
866 s
= ADDRESS_FAMILY_YES
;
868 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
869 "Failed to parse DHCP option, ignoring: %s", rvalue
);
873 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
874 "DHCP=%s is deprecated, please use DHCP=%s instead.",
875 rvalue
, address_family_boolean_to_string(s
));
882 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
883 [DHCP_CLIENT_ID_MAC
] = "mac",
884 [DHCP_CLIENT_ID_DUID
] = "duid",
885 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
888 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
889 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
890 "Failed to parse client identifier type");
892 int config_parse_ipv6token(
894 const char *filename
,
897 unsigned section_line
,
904 union in_addr_union buffer
;
905 struct in6_addr
*token
= data
;
913 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
915 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
916 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
920 if (in_addr_is_null(AF_INET6
, &buffer
)) {
921 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
922 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
926 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
927 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
928 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
937 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
938 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
939 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
940 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
943 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
945 int config_parse_ipv6_privacy_extensions(
947 const char *filename
,
950 unsigned section_line
,
957 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
963 assert(ipv6_privacy_extensions
);
965 /* Our enum shall be a superset of booleans, hence first try
966 * to parse as boolean, and then as enum */
968 k
= parse_boolean(rvalue
);
970 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
972 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
974 IPv6PrivacyExtensions s
;
976 s
= ipv6_privacy_extensions_from_string(rvalue
);
979 if (streq(rvalue
, "kernel"))
980 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
982 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
983 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
988 *ipv6_privacy_extensions
= s
;
994 int config_parse_hostname(
996 const char *filename
,
999 unsigned section_line
,
1006 _cleanup_free_
char *hn
= NULL
;
1007 char **hostname
= data
;
1014 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1018 if (!hostname_is_valid(hn
, false)) {
1019 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1020 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1024 r
= dns_name_is_valid(hn
);
1026 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1027 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1031 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1032 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1036 return free_and_replace(*hostname
, hn
);
1039 int config_parse_timezone(
1041 const char *filename
,
1043 const char *section
,
1044 unsigned section_line
,
1051 _cleanup_free_
char *tz
= NULL
;
1052 char **datap
= data
;
1059 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1063 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1064 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1065 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1069 return free_and_replace(*datap
, tz
);
1072 int config_parse_dhcp_server_dns(
1074 const char *filename
,
1076 const char *section
,
1077 unsigned section_line
,
1085 const char *p
= rvalue
;
1093 _cleanup_free_
char *w
= NULL
;
1094 struct in_addr a
, *m
;
1096 r
= extract_first_word(&p
, &w
, NULL
, 0);
1100 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1101 "Failed to extract word, ignoring: %s", rvalue
);
1107 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1108 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1109 "Failed to parse DNS server address, ignoring: %s", w
);
1113 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1117 m
[n
->n_dhcp_server_dns
++] = a
;
1118 n
->dhcp_server_dns
= m
;
1124 int config_parse_radv_dns(
1126 const char *filename
,
1128 const char *section
,
1129 unsigned section_line
,
1137 const char *p
= rvalue
;
1145 _cleanup_free_
char *w
= NULL
;
1146 union in_addr_union a
;
1148 r
= extract_first_word(&p
, &w
, NULL
, 0);
1152 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1153 "Failed to extract word, ignoring: %s", rvalue
);
1159 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1162 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1166 m
[n
->n_router_dns
++] = a
.in6
;
1170 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1171 "Failed to parse DNS server address, ignoring: %s", w
);
1177 int config_parse_radv_search_domains(
1179 const char *filename
,
1181 const char *section
,
1182 unsigned section_line
,
1190 const char *p
= rvalue
;
1198 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1200 r
= extract_first_word(&p
, &w
, NULL
, 0);
1204 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1205 "Failed to extract word, ignoring: %s", rvalue
);
1211 r
= dns_name_apply_idna(w
, &idna
);
1213 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1214 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1217 /* transfer ownership to simplify subsequent operations */
1220 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1224 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1232 int config_parse_dhcp_server_ntp(
1234 const char *filename
,
1236 const char *section
,
1237 unsigned section_line
,
1245 const char *p
= rvalue
;
1253 _cleanup_free_
char *w
= NULL
;
1254 struct in_addr a
, *m
;
1256 r
= extract_first_word(&p
, &w
, NULL
, 0);
1260 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1261 "Failed to extract word, ignoring: %s", rvalue
);
1267 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1268 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1269 "Failed to parse NTP server address, ignoring: %s", w
);
1273 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1277 m
[n
->n_dhcp_server_ntp
++] = a
;
1278 n
->dhcp_server_ntp
= m
;
1282 int config_parse_dns(
1284 const char *filename
,
1286 const char *section
,
1287 unsigned section_line
,
1294 Network
*n
= userdata
;
1302 _cleanup_free_
char *w
= NULL
;
1303 union in_addr_union a
;
1304 struct in_addr_data
*m
;
1307 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1311 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1312 "Invalid syntax, ignoring: %s", rvalue
);
1318 r
= in_addr_from_string_auto(w
, &family
, &a
);
1320 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1321 "Failed to parse dns server address, ignoring: %s", w
);
1325 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1329 m
[n
->n_dns
++] = (struct in_addr_data
) {
1340 int config_parse_dnssec_negative_trust_anchors(
1342 const char *filename
,
1344 const char *section
,
1345 unsigned section_line
,
1352 const char *p
= rvalue
;
1360 if (isempty(rvalue
)) {
1361 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1366 _cleanup_free_
char *w
= NULL
;
1368 r
= extract_first_word(&p
, &w
, NULL
, 0);
1370 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1371 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1377 r
= dns_name_is_valid(w
);
1379 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1380 "%s is not a valid domain name, ignoring.", w
);
1384 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1388 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1398 int config_parse_ntp(
1400 const char *filename
,
1402 const char *section
,
1403 unsigned section_line
,
1417 if (isempty(rvalue
)) {
1423 _cleanup_free_
char *w
= NULL
;
1425 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1429 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1430 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1436 r
= dns_name_is_valid_or_address(w
);
1438 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1439 "%s is not a valid domain name or IP address, ignoring.", w
);
1443 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1444 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1445 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1446 MAX_NTP_SERVERS
, w
);
1450 r
= strv_consume(l
, TAKE_PTR(w
));
1458 int config_parse_dhcp_user_class(
1460 const char *filename
,
1462 const char *section
,
1463 unsigned section_line
,
1477 if (isempty(rvalue
)) {
1483 _cleanup_free_
char *w
= NULL
;
1485 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1489 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1490 "Failed to split user classes option, ignoring: %s", rvalue
);
1496 if (strlen(w
) > 255) {
1497 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1498 "%s length is not in the range 1-255, ignoring.", w
);
1502 r
= strv_push(l
, w
);
1512 int config_parse_section_route_table(
1514 const char *filename
,
1516 const char *section
,
1517 unsigned section_line
,
1524 Network
*network
= data
;
1533 r
= safe_atou32(rvalue
, &rt
);
1535 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1536 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1540 if (streq_ptr(section
, "DHCP")) {
1541 network
->dhcp_route_table
= rt
;
1542 network
->dhcp_route_table_set
= true;
1543 } else { /* section is IPv6AcceptRA */
1544 network
->ipv6_accept_ra_route_table
= rt
;
1545 network
->ipv6_accept_ra_route_table_set
= true;
1551 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1552 "Failed to parse DHCP use domains setting");
1554 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1555 [DHCP_USE_DOMAINS_NO
] = "no",
1556 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1557 [DHCP_USE_DOMAINS_YES
] = "yes",
1560 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1562 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1564 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1565 [LLDP_MODE_NO
] = "no",
1566 [LLDP_MODE_YES
] = "yes",
1567 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1570 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
1572 int config_parse_iaid(const char *unit
,
1573 const char *filename
,
1575 const char *section
,
1576 unsigned section_line
,
1582 Network
*network
= data
;
1591 r
= safe_atou32(rvalue
, &iaid
);
1593 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1594 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1598 network
->iaid
= iaid
;
1599 network
->iaid_set
= true;
1604 int config_parse_required_for_online(
1606 const char *filename
,
1608 const char *section
,
1609 unsigned section_line
,
1616 Network
*network
= data
;
1617 LinkOperationalState s
;
1618 bool required
= true;
1621 if (isempty(rvalue
)) {
1622 network
->required_for_online
= true;
1623 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1627 s
= link_operstate_from_string(rvalue
);
1629 r
= parse_boolean(rvalue
);
1631 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1632 "Failed to parse %s= setting, ignoring assignment: %s",
1638 s
= LINK_OPERSTATE_DEGRADED
;
1641 network
->required_for_online
= required
;
1642 network
->required_operstate_for_online
= s
;