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 static void network_config_hash_func(const NetworkConfigSection
*c
, struct siphash
*state
) {
30 siphash24_compress(c
->filename
, strlen(c
->filename
), state
);
31 siphash24_compress(&c
->line
, sizeof(c
->line
), state
);
34 static int network_config_compare_func(const NetworkConfigSection
*x
, const NetworkConfigSection
*y
) {
37 r
= strcmp(x
->filename
, y
->filename
);
41 return CMP(x
->line
, y
->line
);
44 DEFINE_HASH_OPS(network_config_hash_ops
, NetworkConfigSection
, network_config_hash_func
, network_config_compare_func
);
46 int network_config_section_new(const char *filename
, unsigned line
, NetworkConfigSection
**s
) {
47 NetworkConfigSection
*cs
;
49 cs
= malloc0(offsetof(NetworkConfigSection
, filename
) + strlen(filename
) + 1);
53 strcpy(cs
->filename
, filename
);
61 void network_config_section_free(NetworkConfigSection
*cs
) {
65 /* Set defaults following RFC7844 */
66 void network_apply_anonymize_if_set(Network
*network
) {
67 if (!network
->dhcp_anonymize
)
70 SHOULD NOT send the Host Name option */
71 network
->dhcp_send_hostname
= false;
72 /* RFC7844 section 3.:
73 MAY contain the Client Identifier option
75 clients MUST use client identifiers based solely
76 on the link-layer address */
77 /* NOTE: Using MAC, as it does not reveal extra information,
78 * and some servers might not answer if this option is not sent */
79 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
81 SHOULD NOT use the Vendor Class Identifier option */
82 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
83 /* RFC7844 section 3.6.:
84 The client intending to protect its privacy SHOULD only request a
85 minimal number of options in the PRL and SHOULD also randomly shuffle
86 the ordering of option codes in the PRL. If this random ordering
87 cannot be implemented, the client MAY order the option codes in the
88 PRL by option code number (lowest to highest).
90 /* NOTE: dhcp_use_mtu is false by default,
91 * though it was not initiallized to any value in network_load_one.
92 * Maybe there should be another var called *send*?
93 * (to use the MTU sent by the server but to do not send
94 * the option in the PRL). */
95 network
->dhcp_use_mtu
= false;
96 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
97 * but this is needed to use them. */
98 network
->dhcp_use_routes
= true;
99 /* RFC7844 section 3.6.
100 * same comments as previous option */
101 network
->dhcp_use_timezone
= false;
104 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
105 const char *kind_string
;
110 assert(network
->manager
);
111 assert(network
->filename
);
117 if (kind
== _NETDEV_KIND_TUNNEL
)
118 kind_string
= "tunnel";
120 kind_string
= netdev_kind_to_string(kind
);
122 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
123 "%s: Invalid NetDev kind of %s, ignoring assignment.",
124 network
->filename
, name
);
127 r
= netdev_get(network
->manager
, name
, &netdev
);
129 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
130 network
->filename
, name
);
132 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
139 NETDEV_KIND_IP6GRETAP
,
142 NETDEV_KIND_IP6TNL
)))
143 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
144 "%s: NetDev %s is not a %s, ignoring assignment",
145 network
->filename
, name
, kind_string
);
147 *ret_netdev
= netdev_ref(netdev
);
151 static int network_resolve_stacked_netdevs(Network
*network
) {
158 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
159 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
161 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
165 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
169 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
171 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
172 network
->filename
, (const char *) name
);
180 static uint32_t network_get_stacked_netdevs_mtu(Network
*network
) {
185 HASHMAP_FOREACH(dev
, network
->stacked_netdevs
, i
)
186 if (dev
->kind
== NETDEV_KIND_VLAN
&& dev
->mtu
> 0)
187 /* See vlan_dev_change_mtu() in kernel.
188 * Note that the additional 4bytes may not be necessary for all devices. */
189 mtu
= MAX(mtu
, dev
->mtu
+ 4);
191 else if (dev
->kind
== NETDEV_KIND_MACVLAN
&& dev
->mtu
> mtu
)
192 /* See macvlan_change_mtu() in kernel. */
198 static int network_verify(Network
*network
) {
199 Address
*address
, *address_next
;
200 Route
*route
, *route_next
;
204 assert(network
->filename
);
206 /* skip out early if configuration does not match the environment */
207 if (!net_match_config(NULL
, NULL
, NULL
, NULL
, NULL
,
208 network
->match_host
, network
->match_virt
, network
->match_kernel_cmdline
,
209 network
->match_kernel_version
, network
->match_arch
,
210 NULL
, NULL
, NULL
, NULL
, NULL
))
211 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
212 "%s: Conditions in the file do not match the system environment, skipping.",
215 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
216 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
217 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
218 (void) network_resolve_stacked_netdevs(network
);
220 /* Free unnecessary entries. */
221 network
->bond_name
= mfree(network
->bond_name
);
222 network
->bridge_name
= mfree(network
->bridge_name
);
223 network
->vrf_name
= mfree(network
->vrf_name
);
224 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
227 /* Bonding slave does not support addressing. */
228 if (network
->ipv6_accept_ra
> 0) {
229 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
231 network
->ipv6_accept_ra
= 0;
233 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
234 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
236 network
->link_local
= ADDRESS_FAMILY_NO
;
238 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
239 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
241 network
->dhcp
= ADDRESS_FAMILY_NO
;
243 if (network
->dhcp_server
) {
244 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
246 network
->dhcp_server
= false;
248 if (network
->n_static_addresses
> 0) {
249 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
251 while ((address
= network
->static_addresses
))
252 address_free(address
);
254 if (network
->n_static_routes
> 0) {
255 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
257 while ((route
= network
->static_routes
))
262 if (network
->link_local
< 0)
263 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
265 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
266 network
->ipv6_accept_ra
= false;
268 /* IPMasquerade=yes implies IPForward=yes */
269 if (network
->ip_masquerade
)
270 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
272 network
->mtu_is_set
= network
->mtu
> 0;
273 mtu
= network_get_stacked_netdevs_mtu(network
);
274 if (network
->mtu
< mtu
) {
275 if (network
->mtu_is_set
)
276 log_notice("%s: Bumping MTUBytes= from %"PRIu32
" to %"PRIu32
" because of stacked device",
277 network
->filename
, network
->mtu
, mtu
);
281 if (network
->mtu_is_set
&& network
->dhcp_use_mtu
) {
282 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
283 "Disabling UseMTU=.", network
->filename
);
284 network
->dhcp_use_mtu
= false;
287 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
288 if (address
->family
== AF_UNSPEC
) {
289 log_warning("%s: Address section without Address= field configured. "
290 "Ignoring [Address] section from line %u.",
291 network
->filename
, address
->section
->line
);
293 address_free(address
);
296 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
) {
297 if (route
->family
== AF_UNSPEC
) {
298 log_warning("%s: Route section without Gateway=, Destination=, Source=, "
299 "or PreferredSource= field configured. "
300 "Ignoring [Route] section from line %u.",
301 network
->filename
, route
->section
->line
);
307 if (network
->n_static_addresses
== 0 &&
308 in_addr_is_null(route
->family
, &route
->gw
) == 0 &&
309 route
->gateway_onlink
< 0) {
310 log_warning("%s: Gateway= without static address configured. "
311 "Enabling GatewayOnLink= option.",
313 route
->gateway_onlink
= true;
320 int network_load_one(Manager
*manager
, const char *filename
) {
321 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
322 _cleanup_(network_freep
) Network
*network
= NULL
;
323 _cleanup_fclose_
FILE *file
= NULL
;
324 const char *dropin_dirname
;
331 file
= fopen(filename
, "re");
339 if (null_or_empty_fd(fileno(file
))) {
340 log_debug("Skipping empty file: %s", filename
);
344 fname
= strdup(filename
);
348 name
= strdup(basename(filename
));
352 d
= strrchr(name
, '.');
358 dropin_dirname
= strjoina(name
, ".network.d");
360 network
= new(Network
, 1);
364 *network
= (Network
) {
365 .filename
= TAKE_PTR(fname
),
366 .name
= TAKE_PTR(name
),
368 .required_for_online
= true,
369 .dhcp
= ADDRESS_FAMILY_NO
,
370 .dhcp_use_ntp
= true,
371 .dhcp_use_dns
= true,
372 .dhcp_use_hostname
= true,
373 .dhcp_use_routes
= true,
374 /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
375 .dhcp_send_hostname
= true,
376 /* To enable/disable RFC7844 Anonymity Profiles */
377 .dhcp_anonymize
= false,
378 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
379 /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
380 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
381 .dhcp_route_table
= RT_TABLE_MAIN
,
382 .dhcp_route_table_set
= false,
383 /* NOTE: from man: UseMTU=... Defaults to false*/
384 .dhcp_use_mtu
= false,
385 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
386 .dhcp_use_timezone
= false,
387 .rapid_commit
= true,
389 .dhcp_server_emit_dns
= true,
390 .dhcp_server_emit_ntp
= true,
391 .dhcp_server_emit_router
= true,
392 .dhcp_server_emit_timezone
= true,
394 .router_emit_dns
= true,
395 .router_emit_domains
= true,
400 .allow_port_to_be_root
= -1,
402 .multicast_to_unicast
= -1,
403 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
405 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
407 .dns_default_route
= -1,
408 .llmnr
= RESOLVE_SUPPORT_YES
,
409 .mdns
= RESOLVE_SUPPORT_NO
,
410 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
411 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
413 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
414 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
416 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
417 .ipv6_accept_ra
= -1,
418 .ipv6_dad_transmits
= -1,
419 .ipv6_hop_limit
= -1,
420 .ipv6_proxy_ndp
= -1,
421 .duid
.type
= _DUID_TYPE_INVALID
,
426 .ipv6_accept_ra_use_dns
= true,
427 .ipv6_accept_ra_use_autonomous_prefix
= true,
428 .ipv6_accept_ra_use_onlink_prefix
= true,
429 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
430 .ipv6_accept_ra_route_table_set
= false,
432 .can_triple_sampling
= -1,
435 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
442 "RoutingPolicyRule\0"
445 "DHCPv4\0" /* compat */
448 "IPv6NDPProxyAddress\0"
452 "IPv6PrefixDelegation\0"
455 config_item_perf_lookup
, network_network_gperf_lookup
,
456 CONFIG_PARSE_WARN
, network
);
460 network_apply_anonymize_if_set(network
);
462 LIST_PREPEND(networks
, manager
->networks
, network
);
463 network
->manager
= manager
;
465 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
469 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
473 if (network_verify(network
) < 0)
480 int network_load(Manager
*manager
) {
482 _cleanup_strv_free_
char **files
= NULL
;
488 while ((network
= manager
->networks
))
489 network_free(network
);
491 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
493 return log_error_errno(r
, "Failed to enumerate network files: %m");
495 STRV_FOREACH_BACKWARDS(f
, files
) {
496 r
= network_load_one(manager
, *f
);
504 void network_free(Network
*network
) {
505 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
506 RoutingPolicyRule
*rule
;
517 free(network
->filename
);
519 set_free_free(network
->match_mac
);
520 strv_free(network
->match_path
);
521 strv_free(network
->match_driver
);
522 strv_free(network
->match_type
);
523 strv_free(network
->match_name
);
525 free(network
->description
);
526 free(network
->dhcp_vendor_class_identifier
);
527 strv_free(network
->dhcp_user_class
);
528 free(network
->dhcp_hostname
);
532 strv_free(network
->ntp
);
534 ordered_set_free_free(network
->search_domains
);
535 ordered_set_free_free(network
->route_domains
);
536 strv_free(network
->bind_carrier
);
538 ordered_set_free_free(network
->router_search_domains
);
539 free(network
->router_dns
);
541 free(network
->bridge_name
);
542 free(network
->bond_name
);
543 free(network
->vrf_name
);
544 hashmap_free_free_key(network
->stacked_netdev_names
);
545 netdev_unref(network
->bridge
);
546 netdev_unref(network
->bond
);
547 netdev_unref(network
->vrf
);
548 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
550 while ((route
= network
->static_routes
))
553 while ((address
= network
->static_addresses
))
554 address_free(address
);
556 while ((fdb_entry
= network
->static_fdb_entries
))
557 fdb_entry_free(fdb_entry
);
559 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
560 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
562 while ((neighbor
= network
->neighbors
))
563 neighbor_free(neighbor
);
565 while ((label
= network
->address_labels
))
566 address_label_free(label
);
568 while ((prefix
= network
->static_prefixes
))
571 while ((rule
= network
->rules
))
572 routing_policy_rule_free(rule
);
574 hashmap_free(network
->addresses_by_section
);
575 hashmap_free(network
->routes_by_section
);
576 hashmap_free(network
->fdb_entries_by_section
);
577 hashmap_free(network
->neighbors_by_section
);
578 hashmap_free(network
->address_labels_by_section
);
579 hashmap_free(network
->prefixes_by_section
);
580 hashmap_free(network
->rules_by_section
);
582 if (network
->manager
) {
583 if (network
->manager
->networks
)
584 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
586 if (network
->manager
->networks_by_name
&& network
->name
)
587 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
589 if (network
->manager
->duids_requesting_uuid
)
590 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
595 condition_free_list(network
->match_host
);
596 condition_free_list(network
->match_virt
);
597 condition_free_list(network
->match_kernel_cmdline
);
598 condition_free_list(network
->match_kernel_version
);
599 condition_free_list(network
->match_arch
);
601 free(network
->dhcp_server_timezone
);
602 free(network
->dhcp_server_dns
);
603 free(network
->dhcp_server_ntp
);
605 set_free_free(network
->dnssec_negative_trust_anchors
);
610 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
617 network
= hashmap_get(manager
->networks_by_name
, name
);
626 int network_get(Manager
*manager
, sd_device
*device
,
627 const char *ifname
, const struct ether_addr
*address
,
629 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
636 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
638 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
640 (void) sd_device_get_devtype(device
, &devtype
);
643 LIST_FOREACH(networks
, network
, manager
->networks
) {
644 if (net_match_config(network
->match_mac
, network
->match_path
,
645 network
->match_driver
, network
->match_type
,
646 network
->match_name
, network
->match_host
,
647 network
->match_virt
, network
->match_kernel_cmdline
,
648 network
->match_kernel_version
, network
->match_arch
,
649 address
, path
, driver
, devtype
, ifname
)) {
650 if (network
->match_name
&& device
) {
652 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
654 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
655 (void) safe_atou8(attr
, &name_assign_type
);
657 if (name_assign_type
== NET_NAME_ENUM
)
658 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
659 ifname
, network
->filename
);
661 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
663 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
675 int network_apply(Network
*network
, Link
*link
) {
681 link
->network
= network
;
683 if (network
->ipv4ll_route
) {
686 r
= route_new_static(network
, NULL
, 0, &route
);
690 r
= inet_pton(AF_INET
, "169.254.0.0", &route
->dst
.in
);
696 route
->family
= AF_INET
;
697 route
->dst_prefixlen
= 16;
698 route
->scope
= RT_SCOPE_LINK
;
699 route
->priority
= IPV4LL_ROUTE_METRIC
;
700 route
->protocol
= RTPROT_STATIC
;
703 if (network
->n_dns
> 0 ||
704 !strv_isempty(network
->ntp
) ||
705 !ordered_set_isempty(network
->search_domains
) ||
706 !ordered_set_isempty(network
->route_domains
))
712 bool network_has_static_ipv6_addresses(Network
*network
) {
717 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
718 if (address
->family
== AF_INET6
)
725 int config_parse_stacked_netdev(const char *unit
,
726 const char *filename
,
729 unsigned section_line
,
735 _cleanup_free_
char *kind_string
= NULL
, *name
= NULL
;
746 if (ltype
== _NETDEV_KIND_TUNNEL
)
747 kind
= _NETDEV_KIND_TUNNEL
;
749 kind_string
= strdup(lvalue
);
753 /* the keys are CamelCase versions of the kind */
754 for (p
= kind_string
; *p
; p
++)
757 kind
= netdev_kind_from_string(kind_string
);
758 if (kind
< 0 || IN_SET(kind
, NETDEV_KIND_BRIDGE
, NETDEV_KIND_BOND
, NETDEV_KIND_VRF
)) {
759 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
760 "Invalid NetDev kind: %s", lvalue
);
765 if (!ifname_valid(rvalue
)) {
766 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
767 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
771 name
= strdup(rvalue
);
775 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
779 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
781 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
782 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
784 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
785 "NetDev '%s' specified twice, ignoring.", name
);
792 int config_parse_domains(
794 const char *filename
,
797 unsigned section_line
,
812 if (isempty(rvalue
)) {
813 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
814 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
820 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
824 r
= extract_first_word(&p
, &w
, NULL
, 0);
826 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
827 "Failed to extract search or route domain, ignoring: %s", rvalue
);
833 is_route
= w
[0] == '~';
834 domain
= is_route
? w
+ 1 : w
;
836 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
837 /* If the root domain appears as is, or the special token "*" is found, we'll
838 * consider this as routing domain, unconditionally. */
840 domain
= "."; /* make sure we don't allow empty strings, thus write the root
843 r
= dns_name_normalize(domain
, 0, &normalized
);
845 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
846 "'%s' is not a valid domain name, ignoring.", domain
);
852 if (is_localhost(domain
)) {
853 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
854 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
860 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
861 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
865 r
= ordered_set_put_strdup(*set
, domain
);
873 int config_parse_ipv4ll(
875 const char *filename
,
878 unsigned section_line
,
885 AddressFamilyBoolean
*link_local
= data
;
892 /* Note that this is mostly like
893 * config_parse_address_family_boolean(), except that it
894 * applies only to IPv4 */
896 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, parse_boolean(rvalue
));
901 int config_parse_dhcp(
903 const char *filename
,
906 unsigned section_line
,
913 AddressFamilyBoolean
*dhcp
= data
, s
;
920 /* Note that this is mostly like
921 * config_parse_address_family_boolean(), except that it
922 * understands some old names for the enum values */
924 s
= address_family_boolean_from_string(rvalue
);
927 /* Previously, we had a slightly different enum here,
928 * support its values for compatbility. */
930 if (streq(rvalue
, "none"))
931 s
= ADDRESS_FAMILY_NO
;
932 else if (streq(rvalue
, "v4"))
933 s
= ADDRESS_FAMILY_IPV4
;
934 else if (streq(rvalue
, "v6"))
935 s
= ADDRESS_FAMILY_IPV6
;
936 else if (streq(rvalue
, "both"))
937 s
= ADDRESS_FAMILY_YES
;
939 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
940 "Failed to parse DHCP option, ignoring: %s", rvalue
);
944 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
945 "DHCP=%s is deprecated, please use DHCP=%s instead.",
946 rvalue
, address_family_boolean_to_string(s
));
953 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
954 [DHCP_CLIENT_ID_MAC
] = "mac",
955 [DHCP_CLIENT_ID_DUID
] = "duid",
956 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
959 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
960 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
961 "Failed to parse client identifier type");
963 int config_parse_ipv6token(
965 const char *filename
,
968 unsigned section_line
,
975 union in_addr_union buffer
;
976 struct in6_addr
*token
= data
;
984 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
986 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
987 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
991 if (in_addr_is_null(AF_INET6
, &buffer
)) {
992 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
993 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
997 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
998 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
999 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1003 *token
= buffer
.in6
;
1008 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1009 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1010 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1011 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1014 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
1016 int config_parse_ipv6_privacy_extensions(
1018 const char *filename
,
1020 const char *section
,
1021 unsigned section_line
,
1028 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
1034 assert(ipv6_privacy_extensions
);
1036 /* Our enum shall be a superset of booleans, hence first try
1037 * to parse as boolean, and then as enum */
1039 k
= parse_boolean(rvalue
);
1041 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
1043 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
1045 IPv6PrivacyExtensions s
;
1047 s
= ipv6_privacy_extensions_from_string(rvalue
);
1050 if (streq(rvalue
, "kernel"))
1051 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1053 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1054 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1059 *ipv6_privacy_extensions
= s
;
1065 int config_parse_hostname(
1067 const char *filename
,
1069 const char *section
,
1070 unsigned section_line
,
1077 _cleanup_free_
char *hn
= NULL
;
1078 char **hostname
= data
;
1085 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1089 if (!hostname_is_valid(hn
, false)) {
1090 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1091 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1095 r
= dns_name_is_valid(hn
);
1097 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1098 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1102 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1103 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1107 return free_and_replace(*hostname
, hn
);
1110 int config_parse_timezone(
1112 const char *filename
,
1114 const char *section
,
1115 unsigned section_line
,
1122 _cleanup_free_
char *tz
= NULL
;
1123 char **datap
= data
;
1130 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1134 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1135 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1136 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1140 return free_and_replace(*datap
, tz
);
1143 int config_parse_dhcp_server_dns(
1145 const char *filename
,
1147 const char *section
,
1148 unsigned section_line
,
1156 const char *p
= rvalue
;
1164 _cleanup_free_
char *w
= NULL
;
1165 struct in_addr a
, *m
;
1167 r
= extract_first_word(&p
, &w
, NULL
, 0);
1171 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1172 "Failed to extract word, ignoring: %s", rvalue
);
1178 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1179 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1180 "Failed to parse DNS server address, ignoring: %s", w
);
1184 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1188 m
[n
->n_dhcp_server_dns
++] = a
;
1189 n
->dhcp_server_dns
= m
;
1195 int config_parse_radv_dns(
1197 const char *filename
,
1199 const char *section
,
1200 unsigned section_line
,
1208 const char *p
= rvalue
;
1216 _cleanup_free_
char *w
= NULL
;
1217 union in_addr_union a
;
1219 r
= extract_first_word(&p
, &w
, NULL
, 0);
1223 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1224 "Failed to extract word, ignoring: %s", rvalue
);
1230 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1233 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1237 m
[n
->n_router_dns
++] = a
.in6
;
1241 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1242 "Failed to parse DNS server address, ignoring: %s", w
);
1248 int config_parse_radv_search_domains(
1250 const char *filename
,
1252 const char *section
,
1253 unsigned section_line
,
1261 const char *p
= rvalue
;
1269 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1271 r
= extract_first_word(&p
, &w
, NULL
, 0);
1275 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1276 "Failed to extract word, ignoring: %s", rvalue
);
1282 r
= dns_name_apply_idna(w
, &idna
);
1284 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1285 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1288 /* transfer ownership to simplify subsequent operations */
1291 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1295 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1303 int config_parse_dhcp_server_ntp(
1305 const char *filename
,
1307 const char *section
,
1308 unsigned section_line
,
1316 const char *p
= rvalue
;
1324 _cleanup_free_
char *w
= NULL
;
1325 struct in_addr a
, *m
;
1327 r
= extract_first_word(&p
, &w
, NULL
, 0);
1331 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1332 "Failed to extract word, ignoring: %s", rvalue
);
1338 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1339 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1340 "Failed to parse NTP server address, ignoring: %s", w
);
1344 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1348 m
[n
->n_dhcp_server_ntp
++] = a
;
1349 n
->dhcp_server_ntp
= m
;
1353 int config_parse_dns(
1355 const char *filename
,
1357 const char *section
,
1358 unsigned section_line
,
1365 Network
*n
= userdata
;
1373 _cleanup_free_
char *w
= NULL
;
1374 union in_addr_union a
;
1375 struct in_addr_data
*m
;
1378 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1382 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1383 "Invalid syntax, ignoring: %s", rvalue
);
1389 r
= in_addr_from_string_auto(w
, &family
, &a
);
1391 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1392 "Failed to parse dns server address, ignoring: %s", w
);
1396 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1400 m
[n
->n_dns
++] = (struct in_addr_data
) {
1411 int config_parse_dnssec_negative_trust_anchors(
1413 const char *filename
,
1415 const char *section
,
1416 unsigned section_line
,
1423 const char *p
= rvalue
;
1431 if (isempty(rvalue
)) {
1432 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1437 _cleanup_free_
char *w
= NULL
;
1439 r
= extract_first_word(&p
, &w
, NULL
, 0);
1441 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1442 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1448 r
= dns_name_is_valid(w
);
1450 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1451 "%s is not a valid domain name, ignoring.", w
);
1455 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1459 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1469 int config_parse_ntp(
1471 const char *filename
,
1473 const char *section
,
1474 unsigned section_line
,
1488 if (isempty(rvalue
)) {
1494 _cleanup_free_
char *w
= NULL
;
1496 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1500 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1501 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1507 r
= dns_name_is_valid_or_address(w
);
1509 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1510 "%s is not a valid domain name or IP address, ignoring.", w
);
1514 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1515 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1516 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1517 MAX_NTP_SERVERS
, w
);
1521 r
= strv_consume(l
, TAKE_PTR(w
));
1529 int config_parse_dhcp_user_class(
1531 const char *filename
,
1533 const char *section
,
1534 unsigned section_line
,
1548 if (isempty(rvalue
)) {
1554 _cleanup_free_
char *w
= NULL
;
1556 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1560 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1561 "Failed to split user classes option, ignoring: %s", rvalue
);
1567 if (strlen(w
) > 255) {
1568 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1569 "%s length is not in the range 1-255, ignoring.", w
);
1573 r
= strv_push(l
, w
);
1583 int config_parse_section_route_table(
1585 const char *filename
,
1587 const char *section
,
1588 unsigned section_line
,
1595 Network
*network
= data
;
1604 r
= safe_atou32(rvalue
, &rt
);
1606 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1607 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1611 if (streq_ptr(section
, "DHCP")) {
1612 network
->dhcp_route_table
= rt
;
1613 network
->dhcp_route_table_set
= true;
1614 } else { /* section is IPv6AcceptRA */
1615 network
->ipv6_accept_ra_route_table
= rt
;
1616 network
->ipv6_accept_ra_route_table_set
= true;
1622 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1623 "Failed to parse DHCP use domains setting");
1625 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1626 [DHCP_USE_DOMAINS_NO
] = "no",
1627 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1628 [DHCP_USE_DOMAINS_YES
] = "yes",
1631 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1633 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1635 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1636 [LLDP_MODE_NO
] = "no",
1637 [LLDP_MODE_YES
] = "yes",
1638 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1641 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
1643 int config_parse_iaid(const char *unit
,
1644 const char *filename
,
1646 const char *section
,
1647 unsigned section_line
,
1653 Network
*network
= data
;
1662 r
= safe_atou32(rvalue
, &iaid
);
1664 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1665 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1669 network
->iaid
= iaid
;
1670 network
->iaid_set
= true;