1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include <linux/netdevice.h>
5 #include "alloc-util.h"
6 #include "conf-files.h"
7 #include "conf-parser.h"
8 #include "dns-domain.h"
10 #include "hostname-util.h"
11 #include "in-addr-util.h"
12 #include "network-internal.h"
13 #include "networkd-manager.h"
14 #include "networkd-network.h"
15 #include "parse-util.h"
17 #include "socket-util.h"
18 #include "stat-util.h"
19 #include "string-table.h"
20 #include "string-util.h"
24 /* Let's assume that anything above this number is a user misconfiguration. */
25 #define MAX_NTP_SERVERS 128
27 /* Set defaults following RFC7844 */
28 void network_apply_anonymize_if_set(Network
*network
) {
29 if (!network
->dhcp_anonymize
)
32 SHOULD NOT send the Host Name option */
33 network
->dhcp_send_hostname
= false;
34 /* RFC7844 section 3.:
35 MAY contain the Client Identifier option
37 clients MUST use client identifiers based solely
38 on the link-layer address */
39 /* NOTE: Using MAC, as it does not reveal extra information,
40 * and some servers might not answer if this option is not sent */
41 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
43 SHOULD NOT use the Vendor Class Identifier option */
44 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
45 /* RFC7844 section 3.6.:
46 The client intending to protect its privacy SHOULD only request a
47 minimal number of options in the PRL and SHOULD also randomly shuffle
48 the ordering of option codes in the PRL. If this random ordering
49 cannot be implemented, the client MAY order the option codes in the
50 PRL by option code number (lowest to highest).
52 /* NOTE: dhcp_use_mtu is false by default,
53 * though it was not initiallized to any value in network_load_one.
54 * Maybe there should be another var called *send*?
55 * (to use the MTU sent by the server but to do not send
56 * the option in the PRL). */
57 network
->dhcp_use_mtu
= false;
58 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
59 * but this is needed to use them. */
60 network
->dhcp_use_routes
= true;
61 /* RFC7844 section 3.6.
62 * same comments as previous option */
63 network
->dhcp_use_timezone
= false;
66 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
67 const char *kind_string
;
71 /* For test-networkd-conf, the check must be earlier than the assertions. */
76 assert(network
->manager
);
77 assert(network
->filename
);
80 if (kind
== _NETDEV_KIND_TUNNEL
)
81 kind_string
= "tunnel";
83 kind_string
= netdev_kind_to_string(kind
);
85 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
86 "%s: Invalid NetDev kind of %s, ignoring assignment.",
87 network
->filename
, name
);
90 r
= netdev_get(network
->manager
, name
, &netdev
);
92 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
93 network
->filename
, name
);
95 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
102 NETDEV_KIND_IP6GRETAP
,
106 NETDEV_KIND_ERSPAN
)))
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 int network_verify(Network
*network
) {
163 Address
*address
, *address_next
;
164 Route
*route
, *route_next
;
165 FdbEntry
*fdb
, *fdb_next
;
166 Neighbor
*neighbor
, *neighbor_next
;
167 AddressLabel
*label
, *label_next
;
168 Prefix
*prefix
, *prefix_next
;
169 RoutingPolicyRule
*rule
, *rule_next
;
173 assert(network
->filename
);
175 /* skip out early if configuration does not match the environment */
176 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
177 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
178 "%s: Conditions in the file do not match the system environment, skipping.",
181 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
182 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
183 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
184 (void) network_resolve_stacked_netdevs(network
);
186 /* Free unnecessary entries. */
187 network
->bond_name
= mfree(network
->bond_name
);
188 network
->bridge_name
= mfree(network
->bridge_name
);
189 network
->vrf_name
= mfree(network
->vrf_name
);
190 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
193 /* Bonding slave does not support addressing. */
194 if (network
->ipv6_accept_ra
> 0) {
195 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
197 network
->ipv6_accept_ra
= 0;
199 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
200 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
202 network
->link_local
= ADDRESS_FAMILY_NO
;
204 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
205 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
207 network
->dhcp
= ADDRESS_FAMILY_NO
;
209 if (network
->dhcp_server
) {
210 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
212 network
->dhcp_server
= false;
214 if (network
->n_static_addresses
> 0) {
215 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
217 while ((address
= network
->static_addresses
))
218 address_free(address
);
220 if (network
->n_static_routes
> 0) {
221 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
223 while ((route
= network
->static_routes
))
228 if (network
->link_local
< 0)
229 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
231 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
232 network
->ipv6_accept_ra
= false;
234 /* IPMasquerade=yes implies IPForward=yes */
235 if (network
->ip_masquerade
)
236 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
238 network
->mtu_is_set
= network
->mtu
> 0;
239 mtu
= network_get_stacked_netdevs_mtu(network
);
240 if (network
->mtu
< mtu
) {
241 if (network
->mtu_is_set
)
242 log_notice("%s: Bumping MTUBytes= from %"PRIu32
" to %"PRIu32
" because of stacked device",
243 network
->filename
, network
->mtu
, mtu
);
247 if (network
->mtu_is_set
&& network
->dhcp_use_mtu
) {
248 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
249 "Disabling UseMTU=.", network
->filename
);
250 network
->dhcp_use_mtu
= false;
253 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
254 if (address_section_verify(address
) < 0)
255 address_free(address
);
257 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
258 if (route_section_verify(route
, network
) < 0)
261 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
262 if (section_is_invalid(fdb
->section
))
265 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
266 if (section_is_invalid(neighbor
->section
))
267 neighbor_free(neighbor
);
269 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
270 if (section_is_invalid(label
->section
))
271 address_label_free(label
);
273 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
274 if (section_is_invalid(prefix
->section
))
277 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
278 if (section_is_invalid(rule
->section
))
279 routing_policy_rule_free(rule
);
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 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
334 .dhcp
= ADDRESS_FAMILY_NO
,
335 .dhcp_use_ntp
= true,
336 .dhcp_use_dns
= true,
337 .dhcp_use_hostname
= true,
338 .dhcp_use_routes
= true,
339 /* NOTE: this var might be overwriten by network_apply_anonymize_if_set */
340 .dhcp_send_hostname
= true,
341 /* To enable/disable RFC7844 Anonymity Profiles */
342 .dhcp_anonymize
= false,
343 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
344 /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */
345 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
346 .dhcp_route_table
= RT_TABLE_MAIN
,
347 .dhcp_route_table_set
= false,
348 /* NOTE: from man: UseMTU=... Defaults to false*/
349 .dhcp_use_mtu
= false,
350 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
351 .dhcp_use_timezone
= false,
352 .rapid_commit
= true,
354 .dhcp_server_emit_dns
= true,
355 .dhcp_server_emit_ntp
= true,
356 .dhcp_server_emit_router
= true,
357 .dhcp_server_emit_timezone
= true,
359 .router_emit_dns
= true,
360 .router_emit_domains
= true,
365 .allow_port_to_be_root
= -1,
367 .multicast_flood
= -1,
368 .multicast_to_unicast
= -1,
369 .neighbor_suppression
= -1,
371 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
373 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
375 .dns_default_route
= -1,
376 .llmnr
= RESOLVE_SUPPORT_YES
,
377 .mdns
= RESOLVE_SUPPORT_NO
,
378 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
379 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
381 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
382 .link_local
= _ADDRESS_FAMILY_BOOLEAN_INVALID
,
384 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
385 .ipv6_accept_ra
= -1,
386 .ipv6_dad_transmits
= -1,
387 .ipv6_hop_limit
= -1,
388 .ipv6_proxy_ndp
= -1,
389 .duid
.type
= _DUID_TYPE_INVALID
,
394 .ipv6_accept_ra_use_dns
= true,
395 .ipv6_accept_ra_use_autonomous_prefix
= true,
396 .ipv6_accept_ra_use_onlink_prefix
= true,
397 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
398 .ipv6_accept_ra_route_table_set
= false,
400 .can_triple_sampling
= -1,
403 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
410 "RoutingPolicyRule\0"
413 "DHCPv4\0" /* compat */
416 "IPv6NDPProxyAddress\0"
420 "IPv6PrefixDelegation\0"
423 config_item_perf_lookup
, network_network_gperf_lookup
,
424 CONFIG_PARSE_WARN
, network
);
428 network_apply_anonymize_if_set(network
);
430 r
= network_add_ipv4ll_route(network
);
432 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
434 LIST_PREPEND(networks
, manager
->networks
, network
);
435 network
->manager
= manager
;
437 r
= hashmap_ensure_allocated(&manager
->networks_by_name
, &string_hash_ops
);
441 r
= hashmap_put(manager
->networks_by_name
, network
->name
, network
);
445 if (network_verify(network
) < 0)
452 int network_load(Manager
*manager
) {
454 _cleanup_strv_free_
char **files
= NULL
;
460 while ((network
= manager
->networks
))
461 network_free(network
);
463 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
465 return log_error_errno(r
, "Failed to enumerate network files: %m");
467 STRV_FOREACH_BACKWARDS(f
, files
) {
468 r
= network_load_one(manager
, *f
);
476 void network_free(Network
*network
) {
477 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
478 RoutingPolicyRule
*rule
;
489 free(network
->filename
);
491 set_free_free(network
->match_mac
);
492 strv_free(network
->match_path
);
493 strv_free(network
->match_driver
);
494 strv_free(network
->match_type
);
495 strv_free(network
->match_name
);
496 condition_free_list(network
->conditions
);
498 free(network
->description
);
499 free(network
->dhcp_vendor_class_identifier
);
500 strv_free(network
->dhcp_user_class
);
501 free(network
->dhcp_hostname
);
505 strv_free(network
->ntp
);
507 ordered_set_free_free(network
->search_domains
);
508 ordered_set_free_free(network
->route_domains
);
509 strv_free(network
->bind_carrier
);
511 ordered_set_free_free(network
->router_search_domains
);
512 free(network
->router_dns
);
514 free(network
->bridge_name
);
515 free(network
->bond_name
);
516 free(network
->vrf_name
);
517 hashmap_free_free_key(network
->stacked_netdev_names
);
518 netdev_unref(network
->bridge
);
519 netdev_unref(network
->bond
);
520 netdev_unref(network
->vrf
);
521 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
523 while ((route
= network
->static_routes
))
526 while ((address
= network
->static_addresses
))
527 address_free(address
);
529 while ((fdb_entry
= network
->static_fdb_entries
))
530 fdb_entry_free(fdb_entry
);
532 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
533 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
535 while ((neighbor
= network
->neighbors
))
536 neighbor_free(neighbor
);
538 while ((label
= network
->address_labels
))
539 address_label_free(label
);
541 while ((prefix
= network
->static_prefixes
))
544 while ((rule
= network
->rules
))
545 routing_policy_rule_free(rule
);
547 hashmap_free(network
->addresses_by_section
);
548 hashmap_free(network
->routes_by_section
);
549 hashmap_free(network
->fdb_entries_by_section
);
550 hashmap_free(network
->neighbors_by_section
);
551 hashmap_free(network
->address_labels_by_section
);
552 hashmap_free(network
->prefixes_by_section
);
553 hashmap_free(network
->rules_by_section
);
555 if (network
->manager
) {
556 if (network
->manager
->networks
)
557 LIST_REMOVE(networks
, network
->manager
->networks
, network
);
559 if (network
->manager
->networks_by_name
&& network
->name
)
560 hashmap_remove(network
->manager
->networks_by_name
, network
->name
);
562 if (network
->manager
->duids_requesting_uuid
)
563 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
568 free(network
->dhcp_server_timezone
);
569 free(network
->dhcp_server_dns
);
570 free(network
->dhcp_server_ntp
);
572 set_free_free(network
->dnssec_negative_trust_anchors
);
577 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
584 network
= hashmap_get(manager
->networks_by_name
, name
);
593 int network_get(Manager
*manager
, sd_device
*device
,
594 const char *ifname
, const struct ether_addr
*address
,
596 const char *path
= NULL
, *driver
= NULL
, *devtype
= NULL
;
603 (void) sd_device_get_property_value(device
, "ID_PATH", &path
);
605 (void) sd_device_get_property_value(device
, "ID_NET_DRIVER", &driver
);
607 (void) sd_device_get_devtype(device
, &devtype
);
610 LIST_FOREACH(networks
, network
, manager
->networks
) {
611 if (net_match_config(network
->match_mac
, network
->match_path
,
612 network
->match_driver
, network
->match_type
,
614 address
, path
, driver
, devtype
, ifname
)) {
615 if (network
->match_name
&& device
) {
617 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
619 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
620 (void) safe_atou8(attr
, &name_assign_type
);
622 if (name_assign_type
== NET_NAME_ENUM
)
623 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
624 ifname
, network
->filename
);
626 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
628 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
640 int network_apply(Network
*network
, Link
*link
) {
644 link
->network
= network
;
646 if (network
->n_dns
> 0 ||
647 !strv_isempty(network
->ntp
) ||
648 !ordered_set_isempty(network
->search_domains
) ||
649 !ordered_set_isempty(network
->route_domains
))
655 bool network_has_static_ipv6_addresses(Network
*network
) {
660 LIST_FOREACH(addresses
, address
, network
->static_addresses
) {
661 if (address
->family
== AF_INET6
)
668 int config_parse_stacked_netdev(const char *unit
,
669 const char *filename
,
672 unsigned section_line
,
678 _cleanup_free_
char *name
= NULL
;
679 NetDevKind kind
= ltype
;
688 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
689 NETDEV_KIND_IPVLAN
, NETDEV_KIND_VXLAN
, NETDEV_KIND_L2TP
,
690 NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
));
692 if (!ifname_valid(rvalue
)) {
693 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
694 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
698 name
= strdup(rvalue
);
702 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
706 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
708 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
709 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
711 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
712 "NetDev '%s' specified twice, ignoring.", name
);
719 int config_parse_domains(
721 const char *filename
,
724 unsigned section_line
,
739 if (isempty(rvalue
)) {
740 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
741 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
747 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
751 r
= extract_first_word(&p
, &w
, NULL
, 0);
753 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
754 "Failed to extract search or route domain, ignoring: %s", rvalue
);
760 is_route
= w
[0] == '~';
761 domain
= is_route
? w
+ 1 : w
;
763 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
764 /* If the root domain appears as is, or the special token "*" is found, we'll
765 * consider this as routing domain, unconditionally. */
767 domain
= "."; /* make sure we don't allow empty strings, thus write the root
770 r
= dns_name_normalize(domain
, 0, &normalized
);
772 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
773 "'%s' is not a valid domain name, ignoring.", domain
);
779 if (is_localhost(domain
)) {
780 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
781 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
787 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
788 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
792 r
= ordered_set_put_strdup(*set
, domain
);
800 int config_parse_ipv4ll(
802 const char *filename
,
805 unsigned section_line
,
812 AddressFamilyBoolean
*link_local
= data
;
819 /* Note that this is mostly like
820 * config_parse_address_family_boolean(), except that it
821 * applies only to IPv4 */
823 SET_FLAG(*link_local
, ADDRESS_FAMILY_IPV4
, parse_boolean(rvalue
));
828 int config_parse_dhcp(
830 const char *filename
,
833 unsigned section_line
,
840 AddressFamilyBoolean
*dhcp
= data
, s
;
847 /* Note that this is mostly like
848 * config_parse_address_family_boolean(), except that it
849 * understands some old names for the enum values */
851 s
= address_family_boolean_from_string(rvalue
);
854 /* Previously, we had a slightly different enum here,
855 * support its values for compatbility. */
857 if (streq(rvalue
, "none"))
858 s
= ADDRESS_FAMILY_NO
;
859 else if (streq(rvalue
, "v4"))
860 s
= ADDRESS_FAMILY_IPV4
;
861 else if (streq(rvalue
, "v6"))
862 s
= ADDRESS_FAMILY_IPV6
;
863 else if (streq(rvalue
, "both"))
864 s
= ADDRESS_FAMILY_YES
;
866 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
867 "Failed to parse DHCP option, ignoring: %s", rvalue
);
871 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
872 "DHCP=%s is deprecated, please use DHCP=%s instead.",
873 rvalue
, address_family_boolean_to_string(s
));
880 static const char* const dhcp_client_identifier_table
[_DHCP_CLIENT_ID_MAX
] = {
881 [DHCP_CLIENT_ID_MAC
] = "mac",
882 [DHCP_CLIENT_ID_DUID
] = "duid",
883 [DHCP_CLIENT_ID_DUID_ONLY
] = "duid-only",
886 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_client_identifier
, DHCPClientIdentifier
);
887 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_client_identifier
, dhcp_client_identifier
, DHCPClientIdentifier
,
888 "Failed to parse client identifier type");
890 int config_parse_ipv6token(
892 const char *filename
,
895 unsigned section_line
,
902 union in_addr_union buffer
;
903 struct in6_addr
*token
= data
;
911 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
913 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
914 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
918 if (in_addr_is_null(AF_INET6
, &buffer
)) {
919 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
920 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
924 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
925 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
926 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
935 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
936 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
937 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
938 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
941 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions
, IPv6PrivacyExtensions
);
943 int config_parse_ipv6_privacy_extensions(
945 const char *filename
,
948 unsigned section_line
,
955 IPv6PrivacyExtensions
*ipv6_privacy_extensions
= data
;
961 assert(ipv6_privacy_extensions
);
963 /* Our enum shall be a superset of booleans, hence first try
964 * to parse as boolean, and then as enum */
966 k
= parse_boolean(rvalue
);
968 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_YES
;
970 *ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
;
972 IPv6PrivacyExtensions s
;
974 s
= ipv6_privacy_extensions_from_string(rvalue
);
977 if (streq(rvalue
, "kernel"))
978 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
980 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
981 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
986 *ipv6_privacy_extensions
= s
;
992 int config_parse_hostname(
994 const char *filename
,
997 unsigned section_line
,
1004 _cleanup_free_
char *hn
= NULL
;
1005 char **hostname
= data
;
1012 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1016 if (!hostname_is_valid(hn
, false)) {
1017 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1018 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1022 r
= dns_name_is_valid(hn
);
1024 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1025 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1029 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1030 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1034 return free_and_replace(*hostname
, hn
);
1037 int config_parse_timezone(
1039 const char *filename
,
1041 const char *section
,
1042 unsigned section_line
,
1049 _cleanup_free_
char *tz
= NULL
;
1050 char **datap
= data
;
1057 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1061 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1062 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1063 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1067 return free_and_replace(*datap
, tz
);
1070 int config_parse_dhcp_server_dns(
1072 const char *filename
,
1074 const char *section
,
1075 unsigned section_line
,
1083 const char *p
= rvalue
;
1091 _cleanup_free_
char *w
= NULL
;
1092 struct in_addr a
, *m
;
1094 r
= extract_first_word(&p
, &w
, NULL
, 0);
1098 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1099 "Failed to extract word, ignoring: %s", rvalue
);
1105 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1106 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1107 "Failed to parse DNS server address, ignoring: %s", w
);
1111 m
= reallocarray(n
->dhcp_server_dns
, n
->n_dhcp_server_dns
+ 1, sizeof(struct in_addr
));
1115 m
[n
->n_dhcp_server_dns
++] = a
;
1116 n
->dhcp_server_dns
= m
;
1122 int config_parse_radv_dns(
1124 const char *filename
,
1126 const char *section
,
1127 unsigned section_line
,
1135 const char *p
= rvalue
;
1143 _cleanup_free_
char *w
= NULL
;
1144 union in_addr_union a
;
1146 r
= extract_first_word(&p
, &w
, NULL
, 0);
1150 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1151 "Failed to extract word, ignoring: %s", rvalue
);
1157 if (in_addr_from_string(AF_INET6
, w
, &a
) >= 0) {
1160 m
= reallocarray(n
->router_dns
, n
->n_router_dns
+ 1, sizeof(struct in6_addr
));
1164 m
[n
->n_router_dns
++] = a
.in6
;
1168 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1169 "Failed to parse DNS server address, ignoring: %s", w
);
1175 int config_parse_radv_search_domains(
1177 const char *filename
,
1179 const char *section
,
1180 unsigned section_line
,
1188 const char *p
= rvalue
;
1196 _cleanup_free_
char *w
= NULL
, *idna
= NULL
;
1198 r
= extract_first_word(&p
, &w
, NULL
, 0);
1202 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1203 "Failed to extract word, ignoring: %s", rvalue
);
1209 r
= dns_name_apply_idna(w
, &idna
);
1211 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1212 "Failed to apply IDNA to domain name '%s', ignoring: %m", w
);
1215 /* transfer ownership to simplify subsequent operations */
1218 r
= ordered_set_ensure_allocated(&n
->router_search_domains
, &string_hash_ops
);
1222 r
= ordered_set_consume(n
->router_search_domains
, TAKE_PTR(idna
));
1230 int config_parse_dhcp_server_ntp(
1232 const char *filename
,
1234 const char *section
,
1235 unsigned section_line
,
1243 const char *p
= rvalue
;
1251 _cleanup_free_
char *w
= NULL
;
1252 struct in_addr a
, *m
;
1254 r
= extract_first_word(&p
, &w
, NULL
, 0);
1258 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1259 "Failed to extract word, ignoring: %s", rvalue
);
1265 if (inet_pton(AF_INET
, w
, &a
) <= 0) {
1266 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1267 "Failed to parse NTP server address, ignoring: %s", w
);
1271 m
= reallocarray(n
->dhcp_server_ntp
, n
->n_dhcp_server_ntp
+ 1, sizeof(struct in_addr
));
1275 m
[n
->n_dhcp_server_ntp
++] = a
;
1276 n
->dhcp_server_ntp
= m
;
1280 int config_parse_dns(
1282 const char *filename
,
1284 const char *section
,
1285 unsigned section_line
,
1292 Network
*n
= userdata
;
1300 _cleanup_free_
char *w
= NULL
;
1301 union in_addr_union a
;
1302 struct in_addr_data
*m
;
1305 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1309 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1310 "Invalid syntax, ignoring: %s", rvalue
);
1316 r
= in_addr_from_string_auto(w
, &family
, &a
);
1318 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1319 "Failed to parse dns server address, ignoring: %s", w
);
1323 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1327 m
[n
->n_dns
++] = (struct in_addr_data
) {
1338 int config_parse_dnssec_negative_trust_anchors(
1340 const char *filename
,
1342 const char *section
,
1343 unsigned section_line
,
1350 const char *p
= rvalue
;
1358 if (isempty(rvalue
)) {
1359 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1364 _cleanup_free_
char *w
= NULL
;
1366 r
= extract_first_word(&p
, &w
, NULL
, 0);
1368 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1369 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1375 r
= dns_name_is_valid(w
);
1377 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1378 "%s is not a valid domain name, ignoring.", w
);
1382 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1386 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1396 int config_parse_ntp(
1398 const char *filename
,
1400 const char *section
,
1401 unsigned section_line
,
1415 if (isempty(rvalue
)) {
1421 _cleanup_free_
char *w
= NULL
;
1423 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1427 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1428 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1434 r
= dns_name_is_valid_or_address(w
);
1436 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1437 "%s is not a valid domain name or IP address, ignoring.", w
);
1441 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1442 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1443 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1444 MAX_NTP_SERVERS
, w
);
1448 r
= strv_consume(l
, TAKE_PTR(w
));
1456 int config_parse_dhcp_user_class(
1458 const char *filename
,
1460 const char *section
,
1461 unsigned section_line
,
1475 if (isempty(rvalue
)) {
1481 _cleanup_free_
char *w
= NULL
;
1483 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1487 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1488 "Failed to split user classes option, ignoring: %s", rvalue
);
1494 if (strlen(w
) > 255) {
1495 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1496 "%s length is not in the range 1-255, ignoring.", w
);
1500 r
= strv_push(l
, w
);
1510 int config_parse_section_route_table(
1512 const char *filename
,
1514 const char *section
,
1515 unsigned section_line
,
1522 Network
*network
= data
;
1531 r
= safe_atou32(rvalue
, &rt
);
1533 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1534 "Failed to parse RouteTable=%s, ignoring assignment: %m", rvalue
);
1538 if (streq_ptr(section
, "DHCP")) {
1539 network
->dhcp_route_table
= rt
;
1540 network
->dhcp_route_table_set
= true;
1541 } else { /* section is IPv6AcceptRA */
1542 network
->ipv6_accept_ra_route_table
= rt
;
1543 network
->ipv6_accept_ra_route_table_set
= true;
1549 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1550 "Failed to parse DHCP use domains setting");
1552 static const char* const dhcp_use_domains_table
[_DHCP_USE_DOMAINS_MAX
] = {
1553 [DHCP_USE_DOMAINS_NO
] = "no",
1554 [DHCP_USE_DOMAINS_ROUTE
] = "route",
1555 [DHCP_USE_DOMAINS_YES
] = "yes",
1558 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dhcp_use_domains
, DHCPUseDomains
, DHCP_USE_DOMAINS_YES
);
1560 DEFINE_CONFIG_PARSE_ENUM(config_parse_lldp_mode
, lldp_mode
, LLDPMode
, "Failed to parse LLDP= setting.");
1562 static const char* const lldp_mode_table
[_LLDP_MODE_MAX
] = {
1563 [LLDP_MODE_NO
] = "no",
1564 [LLDP_MODE_YES
] = "yes",
1565 [LLDP_MODE_ROUTERS_ONLY
] = "routers-only",
1568 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(lldp_mode
, LLDPMode
, LLDP_MODE_YES
);
1570 int config_parse_iaid(const char *unit
,
1571 const char *filename
,
1573 const char *section
,
1574 unsigned section_line
,
1580 Network
*network
= data
;
1589 r
= safe_atou32(rvalue
, &iaid
);
1591 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1592 "Unable to read IAID, ignoring assignment: %s", rvalue
);
1596 network
->iaid
= iaid
;
1597 network
->iaid_set
= true;
1602 int config_parse_required_for_online(
1604 const char *filename
,
1606 const char *section
,
1607 unsigned section_line
,
1614 Network
*network
= data
;
1615 LinkOperationalState s
;
1616 bool required
= true;
1619 if (isempty(rvalue
)) {
1620 network
->required_for_online
= true;
1621 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1625 s
= link_operstate_from_string(rvalue
);
1627 r
= parse_boolean(rvalue
);
1629 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1630 "Failed to parse %s= setting, ignoring assignment: %s",
1636 s
= LINK_OPERSTATE_DEGRADED
;
1639 network
->required_for_online
= required
;
1640 network
->required_operstate_for_online
= s
;