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
;
74 assert(network
->manager
);
75 assert(network
->filename
);
81 if (kind
== _NETDEV_KIND_TUNNEL
)
82 kind_string
= "tunnel";
84 kind_string
= netdev_kind_to_string(kind
);
86 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
87 "%s: Invalid NetDev kind of %s, ignoring assignment.",
88 network
->filename
, name
);
91 r
= netdev_get(network
->manager
, name
, &netdev
);
93 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
94 network
->filename
, name
);
96 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
103 NETDEV_KIND_IP6GRETAP
,
106 NETDEV_KIND_IP6TNL
)))
107 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
108 "%s: NetDev %s is not a %s, ignoring assignment",
109 network
->filename
, name
, kind_string
);
111 *ret_netdev
= netdev_ref(netdev
);
115 static int network_resolve_stacked_netdevs(Network
*network
) {
122 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
123 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
125 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
129 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
133 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
135 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
136 network
->filename
, (const char *) name
);
144 static uint32_t network_get_stacked_netdevs_mtu(Network
*network
) {
149 HASHMAP_FOREACH(dev
, network
->stacked_netdevs
, i
)
150 if (dev
->kind
== NETDEV_KIND_VLAN
&& dev
->mtu
> 0)
151 /* See vlan_dev_change_mtu() in kernel.
152 * Note that the additional 4bytes may not be necessary for all devices. */
153 mtu
= MAX(mtu
, dev
->mtu
+ 4);
155 else if (dev
->kind
== NETDEV_KIND_MACVLAN
&& dev
->mtu
> mtu
)
156 /* See macvlan_change_mtu() in kernel. */
162 static int network_verify(Network
*network
) {
163 Address
*address
, *address_next
;
164 Route
*route
, *route_next
;
168 assert(network
->filename
);
170 /* skip out early if configuration does not match the environment */
171 if (!net_match_config(NULL
, NULL
, NULL
, NULL
, NULL
,
172 network
->match_host
, network
->match_virt
, network
->match_kernel_cmdline
,
173 network
->match_kernel_version
, network
->match_arch
,
174 NULL
, NULL
, NULL
, NULL
, NULL
))
175 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
176 "%s: Conditions in the file do not match the system environment, skipping.",
179 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
180 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
181 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
182 (void) network_resolve_stacked_netdevs(network
);
184 /* Free unnecessary entries. */
185 network
->bond_name
= mfree(network
->bond_name
);
186 network
->bridge_name
= mfree(network
->bridge_name
);
187 network
->vrf_name
= mfree(network
->vrf_name
);
188 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
191 /* Bonding slave does not support addressing. */
192 if (network
->ipv6_accept_ra
> 0) {
193 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
195 network
->ipv6_accept_ra
= 0;
197 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
198 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
200 network
->link_local
= ADDRESS_FAMILY_NO
;
202 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
203 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
205 network
->dhcp
= ADDRESS_FAMILY_NO
;
207 if (network
->dhcp_server
) {
208 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
210 network
->dhcp_server
= false;
212 if (network
->n_static_addresses
> 0) {
213 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
215 while ((address
= network
->static_addresses
))
216 address_free(address
);
218 if (network
->n_static_routes
> 0) {
219 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
221 while ((route
= network
->static_routes
))
226 if (network
->link_local
< 0)
227 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
229 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
230 network
->ipv6_accept_ra
= false;
232 /* IPMasquerade=yes implies IPForward=yes */
233 if (network
->ip_masquerade
)
234 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
236 network
->mtu_is_set
= network
->mtu
> 0;
237 mtu
= network_get_stacked_netdevs_mtu(network
);
238 if (network
->mtu
< mtu
) {
239 if (network
->mtu_is_set
)
240 log_notice("%s: Bumping MTUBytes= from %"PRIu32
" to %"PRIu32
" because of stacked device",
241 network
->filename
, network
->mtu
, mtu
);
245 if (network
->mtu_is_set
&& network
->dhcp_use_mtu
) {
246 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
247 "Disabling UseMTU=.", network
->filename
);
248 network
->dhcp_use_mtu
= false;
251 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
252 if (address
->family
== AF_UNSPEC
) {
253 log_warning("%s: Address section without Address= field configured. "
254 "Ignoring [Address] section from line %u.",
255 network
->filename
, address
->section
->line
);
257 address_free(address
);
260 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
) {
261 if (route
->family
== AF_UNSPEC
) {
262 log_warning("%s: Route section without Gateway=, Destination=, Source=, "
263 "or PreferredSource= field configured. "
264 "Ignoring [Route] section from line %u.",
265 network
->filename
, route
->section
->line
);
271 if (network
->n_static_addresses
== 0 &&
272 in_addr_is_null(route
->family
, &route
->gw
) == 0 &&
273 route
->gateway_onlink
< 0) {
274 log_warning("%s: Gateway= without static address configured. "
275 "Enabling GatewayOnLink= option.",
277 route
->gateway_onlink
= true;
284 int network_load_one(Manager
*manager
, const char *filename
) {
285 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
286 _cleanup_(network_freep
) Network
*network
= NULL
;
287 _cleanup_fclose_
FILE *file
= NULL
;
288 const char *dropin_dirname
;
295 file
= fopen(filename
, "re");
303 if (null_or_empty_fd(fileno(file
))) {
304 log_debug("Skipping empty file: %s", filename
);
308 fname
= strdup(filename
);
312 name
= strdup(basename(filename
));
316 d
= strrchr(name
, '.');
322 dropin_dirname
= strjoina(name
, ".network.d");
324 network
= new(Network
, 1);
328 *network
= (Network
) {
329 .filename
= TAKE_PTR(fname
),
330 .name
= TAKE_PTR(name
),
332 .required_for_online
= true,
333 .dhcp
= ADDRESS_FAMILY_NO
,
334 .dhcp_use_ntp
= true,
335 .dhcp_use_dns
= true,
336 .dhcp_use_hostname
= true,
337 .dhcp_use_routes
= true,
338 /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
339 .dhcp_send_hostname
= true,
340 /* To enable/disable RFC7844 Anonymity Profiles */
341 .dhcp_anonymize
= false,
342 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
343 /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
344 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
345 .dhcp_route_table
= RT_TABLE_MAIN
,
346 .dhcp_route_table_set
= false,
347 /* NOTE: from man: UseMTU=... Defaults to false*/
348 .dhcp_use_mtu
= false,
349 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
350 .dhcp_use_timezone
= false,
351 .rapid_commit
= true,
353 .dhcp_server_emit_dns
= true,
354 .dhcp_server_emit_ntp
= true,
355 .dhcp_server_emit_router
= true,
356 .dhcp_server_emit_timezone
= true,
358 .router_emit_dns
= true,
359 .router_emit_domains
= true,
364 .allow_port_to_be_root
= -1,
366 .multicast_to_unicast
= -1,
367 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
369 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
371 .dns_default_route
= -1,
372 .llmnr
= RESOLVE_SUPPORT_YES
,
373 .mdns
= RESOLVE_SUPPORT_NO
,
374 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
375 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
377 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
378 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
380 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
381 .ipv6_accept_ra
= -1,
382 .ipv6_dad_transmits
= -1,
383 .ipv6_hop_limit
= -1,
384 .ipv6_proxy_ndp
= -1,
385 .duid
.type
= _DUID_TYPE_INVALID
,
390 .ipv6_accept_ra_use_dns
= true,
391 .ipv6_accept_ra_use_autonomous_prefix
= true,
392 .ipv6_accept_ra_use_onlink_prefix
= true,
393 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
394 .ipv6_accept_ra_route_table_set
= false,
396 .can_triple_sampling
= -1,
399 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
406 "RoutingPolicyRule\0"
409 "DHCPv4\0" /* compat */
412 "IPv6NDPProxyAddress\0"
416 "IPv6PrefixDelegation\0"
419 config_item_perf_lookup
, network_network_gperf_lookup
,
420 CONFIG_PARSE_WARN
, network
);
424 network_apply_anonymize_if_set(network
);
426 LIST_PREPEND(networks
, manager
->networks
, network
);
427 network
->manager
= manager
;
429 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
433 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
437 if (network_verify(network
) < 0)
444 int network_load(Manager
*manager
) {
446 _cleanup_strv_free_
char **files
= NULL
;
452 while ((network
= manager
->networks
))
453 network_free(network
);
455 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
457 return log_error_errno(r
, "Failed to enumerate network files: %m");
459 STRV_FOREACH_BACKWARDS(f
, files
) {
460 r
= network_load_one(manager
, *f
);
468 void network_free(Network
*network
) {
469 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
470 RoutingPolicyRule
*rule
;
481 free(network
->filename
);
483 set_free_free(network
->match_mac
);
484 strv_free(network
->match_path
);
485 strv_free(network
->match_driver
);
486 strv_free(network
->match_type
);
487 strv_free(network
->match_name
);
489 free(network
->description
);
490 free(network
->dhcp_vendor_class_identifier
);
491 strv_free(network
->dhcp_user_class
);
492 free(network
->dhcp_hostname
);
496 strv_free(network
->ntp
);
498 ordered_set_free_free(network
->search_domains
);
499 ordered_set_free_free(network
->route_domains
);
500 strv_free(network
->bind_carrier
);
502 ordered_set_free_free(network
->router_search_domains
);
503 free(network
->router_dns
);
505 free(network
->bridge_name
);
506 free(network
->bond_name
);
507 free(network
->vrf_name
);
508 hashmap_free_free_key(network
->stacked_netdev_names
);
509 netdev_unref(network
->bridge
);
510 netdev_unref(network
->bond
);
511 netdev_unref(network
->vrf
);
512 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
514 while ((route
= network
->static_routes
))
517 while ((address
= network
->static_addresses
))
518 address_free(address
);
520 while ((fdb_entry
= network
->static_fdb_entries
))
521 fdb_entry_free(fdb_entry
);
523 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
524 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
526 while ((neighbor
= network
->neighbors
))
527 neighbor_free(neighbor
);
529 while ((label
= network
->address_labels
))
530 address_label_free(label
);
532 while ((prefix
= network
->static_prefixes
))
535 while ((rule
= network
->rules
))
536 routing_policy_rule_free(rule
);
538 hashmap_free(network
->addresses_by_section
);
539 hashmap_free(network
->routes_by_section
);
540 hashmap_free(network
->fdb_entries_by_section
);
541 hashmap_free(network
->neighbors_by_section
);
542 hashmap_free(network
->address_labels_by_section
);
543 hashmap_free(network
->prefixes_by_section
);
544 hashmap_free(network
->rules_by_section
);
546 if (network
->manager
) {
547 if (network
->manager
->networks
)
548 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
550 if (network
->manager
->networks_by_name
&& network
->name
)
551 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
553 if (network
->manager
->duids_requesting_uuid
)
554 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
559 condition_free_list(network
->match_host
);
560 condition_free_list(network
->match_virt
);
561 condition_free_list(network
->match_kernel_cmdline
);
562 condition_free_list(network
->match_kernel_version
);
563 condition_free_list(network
->match_arch
);
565 free(network
->dhcp_server_timezone
);
566 free(network
->dhcp_server_dns
);
567 free(network
->dhcp_server_ntp
);
569 set_free_free(network
->dnssec_negative_trust_anchors
);
574 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
581 network
= hashmap_get(manager
->networks_by_name
, name
);
590 int network_get(Manager
*manager
, sd_device
*device
,
591 const char *ifname
, const struct ether_addr
*address
,
593 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
600 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
602 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
604 (void) sd_device_get_devtype(device
, &devtype
);
607 LIST_FOREACH(networks
, network
, manager
->networks
) {
608 if (net_match_config(network
->match_mac
, network
->match_path
,
609 network
->match_driver
, network
->match_type
,
610 network
->match_name
, network
->match_host
,
611 network
->match_virt
, network
->match_kernel_cmdline
,
612 network
->match_kernel_version
, network
->match_arch
,
613 address
, path
, driver
, devtype
, ifname
)) {
614 if (network
->match_name
&& device
) {
616 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
618 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
619 (void) safe_atou8(attr
, &name_assign_type
);
621 if (name_assign_type
== NET_NAME_ENUM
)
622 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
623 ifname
, network
->filename
);
625 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
627 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
639 int network_apply(Network
*network
, Link
*link
) {
645 link
->network
= network
;
647 if (network
->ipv4ll_route
) {
650 r
= route_new_static(network
, NULL
, 0, &route
);
654 r
= inet_pton(AF_INET
, "169.254.0.0", &route
->dst
.in
);
660 route
->family
= AF_INET
;
661 route
->dst_prefixlen
= 16;
662 route
->scope
= RT_SCOPE_LINK
;
663 route
->priority
= IPV4LL_ROUTE_METRIC
;
664 route
->protocol
= RTPROT_STATIC
;
667 if (network
->n_dns
> 0 ||
668 !strv_isempty(network
->ntp
) ||
669 !ordered_set_isempty(network
->search_domains
) ||
670 !ordered_set_isempty(network
->route_domains
))
676 bool network_has_static_ipv6_addresses(Network
*network
) {
681 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
682 if (address
->family
== AF_INET6
)
689 int config_parse_stacked_netdev(const char *unit
,
690 const char *filename
,
693 unsigned section_line
,
699 _cleanup_free_
char *name
= NULL
;
700 NetDevKind kind
= ltype
;
709 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
710 NETDEV_KIND_IPVLAN
, NETDEV_KIND_VXLAN
, _NETDEV_KIND_TUNNEL
));
712 if (!ifname_valid(rvalue
)) {
713 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
714 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
718 name
= strdup(rvalue
);
722 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
726 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
728 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
729 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
731 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
732 "NetDev '%s' specified twice, ignoring.", name
);
739 int config_parse_domains(
741 const char *filename
,
744 unsigned section_line
,
759 if (isempty(rvalue
)) {
760 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
761 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
767 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
771 r
= extract_first_word(&p
, &w
, NULL
, 0);
773 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
774 "Failed to extract search or route domain, ignoring: %s", rvalue
);
780 is_route
= w
[0] == '~';
781 domain
= is_route
? w
+ 1 : w
;
783 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
784 /* If the root domain appears as is, or the special token "*" is found, we'll
785 * consider this as routing domain, unconditionally. */
787 domain
= "."; /* make sure we don't allow empty strings, thus write the root
790 r
= dns_name_normalize(domain
, 0, &normalized
);
792 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
793 "'%s' is not a valid domain name, ignoring.", domain
);
799 if (is_localhost(domain
)) {
800 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
801 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
807 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
808 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
812 r
= ordered_set_put_strdup(*set
, domain
);
820 int config_parse_ipv4ll(
822 const char *filename
,
825 unsigned section_line
,
832 AddressFamilyBoolean
*link_local
= data
;
839 /* Note that this is mostly like
840 * config_parse_address_family_boolean(), except that it
841 * applies only to IPv4 */
843 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, parse_boolean(rvalue
));
848 int config_parse_dhcp(
850 const char *filename
,
853 unsigned section_line
,
860 AddressFamilyBoolean
*dhcp
= data
, s
;
867 /* Note that this is mostly like
868 * config_parse_address_family_boolean(), except that it
869 * understands some old names for the enum values */
871 s
= address_family_boolean_from_string(rvalue
);
874 /* Previously, we had a slightly different enum here,
875 * support its values for compatbility. */
877 if (streq(rvalue
, "none"))
878 s
= ADDRESS_FAMILY_NO
;
879 else if (streq(rvalue
, "v4"))
880 s
= ADDRESS_FAMILY_IPV4
;
881 else if (streq(rvalue
, "v6"))
882 s
= ADDRESS_FAMILY_IPV6
;
883 else if (streq(rvalue
, "both"))
884 s
= ADDRESS_FAMILY_YES
;
886 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
887 "Failed to parse DHCP option, ignoring: %s", rvalue
);
891 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
892 "DHCP=%s is deprecated, please use DHCP=%s instead.",
893 rvalue
, address_family_boolean_to_string(s
));
900 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
901 [DHCP_CLIENT_ID_MAC
] = "mac",
902 [DHCP_CLIENT_ID_DUID
] = "duid",
903 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
906 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
907 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
908 "Failed to parse client identifier type");
910 int config_parse_ipv6token(
912 const char *filename
,
915 unsigned section_line
,
922 union in_addr_union buffer
;
923 struct in6_addr
*token
= data
;
931 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
933 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
934 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
938 if (in_addr_is_null(AF_INET6
, &buffer
)) {
939 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
940 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
944 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
945 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
946 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
955 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
956 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
957 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
958 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
961 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
963 int config_parse_ipv6_privacy_extensions(
965 const char *filename
,
968 unsigned section_line
,
975 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
981 assert(ipv6_privacy_extensions
);
983 /* Our enum shall be a superset of booleans, hence first try
984 * to parse as boolean, and then as enum */
986 k
= parse_boolean(rvalue
);
988 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
990 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
992 IPv6PrivacyExtensions s
;
994 s
= ipv6_privacy_extensions_from_string(rvalue
);
997 if (streq(rvalue
, "kernel"))
998 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1000 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1001 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1006 *ipv6_privacy_extensions
= s
;
1012 int config_parse_hostname(
1014 const char *filename
,
1016 const char *section
,
1017 unsigned section_line
,
1024 _cleanup_free_
char *hn
= NULL
;
1025 char **hostname
= data
;
1032 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1036 if (!hostname_is_valid(hn
, false)) {
1037 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1038 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1042 r
= dns_name_is_valid(hn
);
1044 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1045 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1049 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1050 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1054 return free_and_replace(*hostname
, hn
);
1057 int config_parse_timezone(
1059 const char *filename
,
1061 const char *section
,
1062 unsigned section_line
,
1069 _cleanup_free_
char *tz
= NULL
;
1070 char **datap
= data
;
1077 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1081 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1082 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1083 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1087 return free_and_replace(*datap
, tz
);
1090 int config_parse_dhcp_server_dns(
1092 const char *filename
,
1094 const char *section
,
1095 unsigned section_line
,
1103 const char *p
= rvalue
;
1111 _cleanup_free_
char *w
= NULL
;
1112 struct in_addr a
, *m
;
1114 r
= extract_first_word(&p
, &w
, NULL
, 0);
1118 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1119 "Failed to extract word, ignoring: %s", rvalue
);
1125 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1126 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1127 "Failed to parse DNS server address, ignoring: %s", w
);
1131 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1135 m
[n
->n_dhcp_server_dns
++] = a
;
1136 n
->dhcp_server_dns
= m
;
1142 int config_parse_radv_dns(
1144 const char *filename
,
1146 const char *section
,
1147 unsigned section_line
,
1155 const char *p
= rvalue
;
1163 _cleanup_free_
char *w
= NULL
;
1164 union in_addr_union a
;
1166 r
= extract_first_word(&p
, &w
, NULL
, 0);
1170 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1171 "Failed to extract word, ignoring: %s", rvalue
);
1177 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1180 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1184 m
[n
->n_router_dns
++] = a
.in6
;
1188 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1189 "Failed to parse DNS server address, ignoring: %s", w
);
1195 int config_parse_radv_search_domains(
1197 const char *filename
,
1199 const char *section
,
1200 unsigned section_line
,
1208 const char *p
= rvalue
;
1216 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1218 r
= extract_first_word(&p
, &w
, NULL
, 0);
1222 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1223 "Failed to extract word, ignoring: %s", rvalue
);
1229 r
= dns_name_apply_idna(w
, &idna
);
1231 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1232 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1235 /* transfer ownership to simplify subsequent operations */
1238 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1242 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1250 int config_parse_dhcp_server_ntp(
1252 const char *filename
,
1254 const char *section
,
1255 unsigned section_line
,
1263 const char *p
= rvalue
;
1271 _cleanup_free_
char *w
= NULL
;
1272 struct in_addr a
, *m
;
1274 r
= extract_first_word(&p
, &w
, NULL
, 0);
1278 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1279 "Failed to extract word, ignoring: %s", rvalue
);
1285 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1286 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1287 "Failed to parse NTP server address, ignoring: %s", w
);
1291 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1295 m
[n
->n_dhcp_server_ntp
++] = a
;
1296 n
->dhcp_server_ntp
= m
;
1300 int config_parse_dns(
1302 const char *filename
,
1304 const char *section
,
1305 unsigned section_line
,
1312 Network
*n
= userdata
;
1320 _cleanup_free_
char *w
= NULL
;
1321 union in_addr_union a
;
1322 struct in_addr_data
*m
;
1325 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1329 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1330 "Invalid syntax, ignoring: %s", rvalue
);
1336 r
= in_addr_from_string_auto(w
, &family
, &a
);
1338 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1339 "Failed to parse dns server address, ignoring: %s", w
);
1343 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1347 m
[n
->n_dns
++] = (struct in_addr_data
) {
1358 int config_parse_dnssec_negative_trust_anchors(
1360 const char *filename
,
1362 const char *section
,
1363 unsigned section_line
,
1370 const char *p
= rvalue
;
1378 if (isempty(rvalue
)) {
1379 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1384 _cleanup_free_
char *w
= NULL
;
1386 r
= extract_first_word(&p
, &w
, NULL
, 0);
1388 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1389 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1395 r
= dns_name_is_valid(w
);
1397 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1398 "%s is not a valid domain name, ignoring.", w
);
1402 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1406 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1416 int config_parse_ntp(
1418 const char *filename
,
1420 const char *section
,
1421 unsigned section_line
,
1435 if (isempty(rvalue
)) {
1441 _cleanup_free_
char *w
= NULL
;
1443 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1447 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1448 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1454 r
= dns_name_is_valid_or_address(w
);
1456 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1457 "%s is not a valid domain name or IP address, ignoring.", w
);
1461 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1462 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1463 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1464 MAX_NTP_SERVERS
, w
);
1468 r
= strv_consume(l
, TAKE_PTR(w
));
1476 int config_parse_dhcp_user_class(
1478 const char *filename
,
1480 const char *section
,
1481 unsigned section_line
,
1495 if (isempty(rvalue
)) {
1501 _cleanup_free_
char *w
= NULL
;
1503 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1507 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1508 "Failed to split user classes option, ignoring: %s", rvalue
);
1514 if (strlen(w
) > 255) {
1515 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1516 "%s length is not in the range 1-255, ignoring.", w
);
1520 r
= strv_push(l
, w
);
1530 int config_parse_section_route_table(
1532 const char *filename
,
1534 const char *section
,
1535 unsigned section_line
,
1542 Network
*network
= data
;
1551 r
= safe_atou32(rvalue
, &rt
);
1553 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1554 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1558 if (streq_ptr(section
, "DHCP")) {
1559 network
->dhcp_route_table
= rt
;
1560 network
->dhcp_route_table_set
= true;
1561 } else { /* section is IPv6AcceptRA */
1562 network
->ipv6_accept_ra_route_table
= rt
;
1563 network
->ipv6_accept_ra_route_table_set
= true;
1569 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1570 "Failed to parse DHCP use domains setting");
1572 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1573 [DHCP_USE_DOMAINS_NO
] = "no",
1574 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1575 [DHCP_USE_DOMAINS_YES
] = "yes",
1578 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1580 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1582 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1583 [LLDP_MODE_NO
] = "no",
1584 [LLDP_MODE_YES
] = "yes",
1585 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1588 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
1590 int config_parse_iaid(const char *unit
,
1591 const char *filename
,
1593 const char *section
,
1594 unsigned section_line
,
1600 Network
*network
= data
;
1609 r
= safe_atou32(rvalue
, &iaid
);
1611 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1612 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1616 network
->iaid
= iaid
;
1617 network
->iaid_set
= true;