1 /* SPDX-License-Identifier: LGPL-2.1+ */
4 #include <netinet/in.h>
5 #include <linux/netdevice.h>
7 #include "alloc-util.h"
8 #include "conf-files.h"
9 #include "conf-parser.h"
10 #include "dns-domain.h"
12 #include "hostname-util.h"
13 #include "in-addr-util.h"
14 #include "network-internal.h"
15 #include "networkd-manager.h"
16 #include "networkd-network.h"
17 #include "parse-util.h"
19 #include "socket-util.h"
20 #include "stat-util.h"
21 #include "string-table.h"
22 #include "string-util.h"
26 /* Let's assume that anything above this number is a user misconfiguration. */
27 #define MAX_NTP_SERVERS 128
29 /* Set defaults following RFC7844 */
30 void network_apply_anonymize_if_set(Network
*network
) {
31 if (!network
->dhcp_anonymize
)
34 SHOULD NOT send the Host Name option */
35 network
->dhcp_send_hostname
= false;
36 /* RFC7844 section 3.:
37 MAY contain the Client Identifier option
39 clients MUST use client identifiers based solely
40 on the link-layer address */
41 /* NOTE: Using MAC, as it does not reveal extra information,
42 * and some servers might not answer if this option is not sent */
43 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
45 SHOULD NOT use the Vendor Class Identifier option */
46 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
47 /* RFC7844 section 3.6.:
48 The client intending to protect its privacy SHOULD only request a
49 minimal number of options in the PRL and SHOULD also randomly shuffle
50 the ordering of option codes in the PRL. If this random ordering
51 cannot be implemented, the client MAY order the option codes in the
52 PRL by option code number (lowest to highest).
54 /* NOTE: dhcp_use_mtu is false by default,
55 * though it was not initiallized to any value in network_load_one.
56 * Maybe there should be another var called *send*?
57 * (to use the MTU sent by the server but to do not send
58 * the option in the PRL). */
59 network
->dhcp_use_mtu
= false;
60 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
61 * but this is needed to use them. */
62 network
->dhcp_use_routes
= true;
63 /* RFC7844 section 3.6.
64 * same comments as previous option */
65 network
->dhcp_use_timezone
= false;
68 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
69 const char *kind_string
;
73 /* For test-networkd-conf, the check must be earlier than the assertions. */
78 assert(network
->manager
);
79 assert(network
->filename
);
82 if (kind
== _NETDEV_KIND_TUNNEL
)
83 kind_string
= "tunnel";
85 kind_string
= netdev_kind_to_string(kind
);
87 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
88 "%s: Invalid NetDev kind of %s, ignoring assignment.",
89 network
->filename
, name
);
92 r
= netdev_get(network
->manager
, name
, &netdev
);
94 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
95 network
->filename
, name
);
97 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
104 NETDEV_KIND_IP6GRETAP
,
108 NETDEV_KIND_ERSPAN
)))
109 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
110 "%s: NetDev %s is not a %s, ignoring assignment",
111 network
->filename
, name
, kind_string
);
113 *ret_netdev
= netdev_ref(netdev
);
117 static int network_resolve_stacked_netdevs(Network
*network
) {
124 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
125 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
127 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
131 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
135 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
137 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
138 network
->filename
, (const char *) name
);
146 int network_verify(Network
*network
) {
147 Address
*address
, *address_next
;
148 Route
*route
, *route_next
;
149 FdbEntry
*fdb
, *fdb_next
;
150 Neighbor
*neighbor
, *neighbor_next
;
151 AddressLabel
*label
, *label_next
;
152 Prefix
*prefix
, *prefix_next
;
153 RoutingPolicyRule
*rule
, *rule_next
;
154 NextHop
*nexthop
, *nextnop_next
;
157 assert(network
->filename
);
159 if (set_isempty(network
->match_mac
) && strv_isempty(network
->match_path
) &&
160 strv_isempty(network
->match_driver
) && strv_isempty(network
->match_type
) &&
161 strv_isempty(network
->match_name
) && strv_isempty(network
->match_property
) &&
162 !network
->conditions
)
163 log_warning("%s: No valid settings found in the [Match] section. "
164 "The file will match all interfaces. "
165 "If that is intended, please add Name=* in the [Match] section.",
168 /* skip out early if configuration does not match the environment */
169 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
170 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
171 "%s: Conditions in the file do not match the system environment, skipping.",
174 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
175 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
176 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
177 (void) network_resolve_stacked_netdevs(network
);
179 /* Free unnecessary entries. */
180 network
->bond_name
= mfree(network
->bond_name
);
181 network
->bridge_name
= mfree(network
->bridge_name
);
182 network
->vrf_name
= mfree(network
->vrf_name
);
183 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
186 /* Bonding slave does not support addressing. */
187 if (network
->ipv6_accept_ra
> 0) {
188 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
190 network
->ipv6_accept_ra
= 0;
192 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
193 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
195 network
->link_local
= ADDRESS_FAMILY_NO
;
197 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
198 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
200 network
->dhcp
= ADDRESS_FAMILY_NO
;
202 if (network
->dhcp_server
) {
203 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
205 network
->dhcp_server
= false;
207 if (network
->n_static_addresses
> 0) {
208 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
210 while ((address
= network
->static_addresses
))
211 address_free(address
);
213 if (network
->n_static_routes
> 0) {
214 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
216 while ((route
= network
->static_routes
))
221 if (network
->link_local
< 0)
222 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
224 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
225 if (network
->ipv6_accept_ra
> 0) {
226 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
227 "Disabling IPv6AcceptRA=.", network
->filename
);
228 network
->ipv6_accept_ra
= false;
231 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
232 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
233 "Disabling DHCPv6 client.", network
->filename
);
234 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
237 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
238 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
239 "Disabling IPv6PrefixDelegation=.", network
->filename
);
240 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
244 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
245 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
246 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
247 "Disabling the fallback assignment.", network
->filename
);
248 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
251 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
252 network
->ipv6_accept_ra
= false;
254 /* IPMasquerade=yes implies IPForward=yes */
255 if (network
->ip_masquerade
)
256 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
258 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
259 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
260 "Disabling UseMTU=.", network
->filename
);
261 network
->dhcp_use_mtu
= false;
264 if (network
->dhcp_critical
>= 0) {
265 if (network
->keep_configuration
>= 0)
266 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
267 "Ignoring CriticalConnection=.", network
->filename
);
268 else if (network
->dhcp_critical
)
269 /* CriticalConnection=yes also preserve foreign static configurations. */
270 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
272 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
275 if (network
->keep_configuration
< 0)
276 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
278 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
279 if (address_section_verify(address
) < 0)
280 address_free(address
);
282 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
283 if (route_section_verify(route
, network
) < 0)
286 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
287 if (nexthop_section_verify(nexthop
) < 0)
288 nexthop_free(nexthop
);
290 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
291 if (section_is_invalid(fdb
->section
))
294 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
295 if (neighbor_section_verify(neighbor
) < 0)
296 neighbor_free(neighbor
);
298 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
299 if (section_is_invalid(label
->section
))
300 address_label_free(label
);
302 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
303 if (section_is_invalid(prefix
->section
))
306 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_route_prefixes
)
307 if (section_is_invalid(prefix
->section
))
310 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
311 if (routing_policy_rule_section_verify(rule
) < 0)
312 routing_policy_rule_free(rule
);
317 int network_load_one(Manager
*manager
, const char *filename
) {
318 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
319 _cleanup_(network_unrefp
) Network
*network
= NULL
;
320 _cleanup_fclose_
FILE *file
= NULL
;
321 const char *dropin_dirname
;
328 file
= fopen(filename
, "re");
336 if (null_or_empty_fd(fileno(file
))) {
337 log_debug("Skipping empty file: %s", filename
);
341 fname
= strdup(filename
);
345 name
= strdup(basename(filename
));
349 d
= strrchr(name
, '.');
355 dropin_dirname
= strjoina(name
, ".network.d");
357 network
= new(Network
, 1);
361 *network
= (Network
) {
362 .filename
= TAKE_PTR(fname
),
363 .name
= TAKE_PTR(name
),
368 .required_for_online
= true,
369 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
370 .dhcp
= ADDRESS_FAMILY_NO
,
372 .dhcp_use_ntp
= true,
373 .dhcp_use_sip
= true,
374 .dhcp_use_dns
= true,
375 .dhcp_use_hostname
= true,
376 .dhcp_use_routes
= true,
377 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
378 .dhcp_send_hostname
= true,
379 .dhcp_send_release
= true,
380 /* To enable/disable RFC7844 Anonymity Profiles */
381 .dhcp_anonymize
= false,
382 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
383 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
384 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
385 .dhcp_route_table
= RT_TABLE_MAIN
,
386 .dhcp_route_table_set
= false,
387 /* NOTE: from man: UseMTU=... Defaults to false*/
388 .dhcp_use_mtu
= false,
389 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
390 .dhcp_use_timezone
= false,
391 .rapid_commit
= true,
393 .dhcp6_use_ntp
= true,
394 .dhcp6_use_dns
= true,
396 .dhcp_server_emit_dns
= true,
397 .dhcp_server_emit_ntp
= true,
398 .dhcp_server_emit_sip
= true,
399 .dhcp_server_emit_router
= true,
400 .dhcp_server_emit_timezone
= true,
402 .router_emit_dns
= true,
403 .router_emit_domains
= true,
408 .allow_port_to_be_root
= -1,
410 .multicast_flood
= -1,
411 .multicast_to_unicast
= -1,
412 .neighbor_suppression
= -1,
414 .bridge_proxy_arp
= -1,
415 .bridge_proxy_arp_wifi
= -1,
416 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
417 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
419 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
421 .dns_default_route
= -1,
422 .llmnr
= RESOLVE_SUPPORT_YES
,
423 .mdns
= RESOLVE_SUPPORT_NO
,
424 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
425 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
427 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
428 .link_local
= _ADDRESS_FAMILY_INVALID
,
430 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
431 .ipv6_accept_ra
= -1,
432 .ipv6_dad_transmits
= -1,
433 .ipv6_hop_limit
= -1,
434 .ipv6_proxy_ndp
= -1,
435 .duid
.type
= _DUID_TYPE_INVALID
,
440 .ipv6_accept_ra_use_dns
= true,
441 .ipv6_accept_ra_use_autonomous_prefix
= true,
442 .ipv6_accept_ra_use_onlink_prefix
= true,
443 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
444 .ipv6_accept_ra_route_table_set
= false,
446 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
448 .can_triple_sampling
= -1,
449 .ip_service_type
= -1,
452 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
459 "RoutingPolicyRule\0"
462 "DHCP\0" /* compat */
467 "IPv6NDPProxyAddress\0"
471 "IPv6PrefixDelegation\0"
475 config_item_perf_lookup
, network_network_gperf_lookup
,
476 CONFIG_PARSE_WARN
, network
);
480 network_apply_anonymize_if_set(network
);
482 r
= network_add_ipv4ll_route(network
);
484 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
486 r
= network_add_default_route_on_device(network
);
488 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
491 r
= ordered_hashmap_ensure_allocated(&manager
->networks
, &string_hash_ops
);
495 r
= ordered_hashmap_put(manager
->networks
, network
->name
, network
);
499 if (network_verify(network
) < 0)
506 int network_load(Manager
*manager
) {
507 _cleanup_strv_free_
char **files
= NULL
;
513 ordered_hashmap_clear_with_destructor(manager
->networks
, network_unref
);
515 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
517 return log_error_errno(r
, "Failed to enumerate network files: %m");
519 STRV_FOREACH(f
, files
) {
520 r
= network_load_one(manager
, *f
);
522 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
528 static Network
*network_free(Network
*network
) {
529 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
530 RoutingPolicyRule
*rule
;
542 free(network
->filename
);
544 set_free_free(network
->match_mac
);
545 strv_free(network
->match_path
);
546 strv_free(network
->match_driver
);
547 strv_free(network
->match_type
);
548 strv_free(network
->match_name
);
549 strv_free(network
->match_property
);
550 condition_free_list(network
->conditions
);
552 free(network
->description
);
553 free(network
->dhcp_vendor_class_identifier
);
554 strv_free(network
->dhcp_user_class
);
555 free(network
->dhcp_hostname
);
556 set_free(network
->dhcp_black_listed_ip
);
557 set_free(network
->dhcp_request_options
);
560 strv_free(network
->ntp
);
562 strv_free(network
->sip
);
563 ordered_set_free_free(network
->search_domains
);
564 ordered_set_free_free(network
->route_domains
);
565 strv_free(network
->bind_carrier
);
567 ordered_set_free_free(network
->router_search_domains
);
568 free(network
->router_dns
);
569 set_free_free(network
->ndisc_black_listed_prefix
);
571 free(network
->bridge_name
);
572 free(network
->bond_name
);
573 free(network
->vrf_name
);
574 hashmap_free_free_key(network
->stacked_netdev_names
);
575 netdev_unref(network
->bridge
);
576 netdev_unref(network
->bond
);
577 netdev_unref(network
->vrf
);
578 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
580 while ((route
= network
->static_routes
))
583 while ((nexthop
= network
->static_nexthops
))
584 nexthop_free(nexthop
);
586 while ((address
= network
->static_addresses
))
587 address_free(address
);
589 while ((fdb_entry
= network
->static_fdb_entries
))
590 fdb_entry_free(fdb_entry
);
592 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
593 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
595 while ((neighbor
= network
->neighbors
))
596 neighbor_free(neighbor
);
598 while ((label
= network
->address_labels
))
599 address_label_free(label
);
601 while ((prefix
= network
->static_prefixes
))
604 while ((rule
= network
->rules
))
605 routing_policy_rule_free(rule
);
607 hashmap_free(network
->addresses_by_section
);
608 hashmap_free(network
->routes_by_section
);
609 hashmap_free(network
->nexthops_by_section
);
610 hashmap_free(network
->fdb_entries_by_section
);
611 hashmap_free(network
->neighbors_by_section
);
612 hashmap_free(network
->address_labels_by_section
);
613 hashmap_free(network
->prefixes_by_section
);
614 hashmap_free(network
->rules_by_section
);
616 if (network
->manager
) {
617 if (network
->manager
->networks
&& network
->name
)
618 ordered_hashmap_remove(network
->manager
->networks
, network
->name
);
620 if (network
->manager
->duids_requesting_uuid
)
621 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
626 free(network
->dhcp_server_timezone
);
627 free(network
->dhcp_server_dns
);
628 free(network
->dhcp_server_ntp
);
629 free(network
->dhcp_server_sip
);
631 set_free_free(network
->dnssec_negative_trust_anchors
);
633 ordered_hashmap_free(network
->dhcp_send_options
);
635 return mfree(network
);
638 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
640 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
647 network
= ordered_hashmap_get(manager
->networks
, name
);
656 int network_get(Manager
*manager
, sd_device
*device
,
657 const char *ifname
, const struct ether_addr
*address
,
665 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
666 if (net_match_config(network
->match_mac
, network
->match_path
, network
->match_driver
,
667 network
->match_type
, network
->match_name
, network
->match_property
,
668 device
, address
, ifname
)) {
669 if (network
->match_name
&& device
) {
671 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
673 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
674 (void) safe_atou8(attr
, &name_assign_type
);
676 if (name_assign_type
== NET_NAME_ENUM
)
677 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
678 ifname
, network
->filename
);
680 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
682 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
693 int network_apply(Network
*network
, Link
*link
) {
697 link
->network
= network_ref(network
);
699 if (network
->n_dns
> 0 ||
700 !strv_isempty(network
->ntp
) ||
701 !ordered_set_isempty(network
->search_domains
) ||
702 !ordered_set_isempty(network
->route_domains
))
708 bool network_has_static_ipv6_configurations(Network
*network
) {
716 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
717 if (address
->family
== AF_INET6
)
720 LIST_FOREACH(routes
, route
, network
->static_routes
)
721 if (route
->family
== AF_INET6
)
724 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
725 if (fdb
->family
== AF_INET6
)
728 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
729 if (neighbor
->family
== AF_INET6
)
732 if (!LIST_IS_EMPTY(network
->address_labels
))
735 if (!LIST_IS_EMPTY(network
->static_prefixes
))
741 int config_parse_stacked_netdev(const char *unit
,
742 const char *filename
,
745 unsigned section_line
,
751 _cleanup_free_
char *name
= NULL
;
752 NetDevKind kind
= ltype
;
761 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
762 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
763 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
766 if (!ifname_valid(rvalue
)) {
767 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
768 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
772 name
= strdup(rvalue
);
776 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
780 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
782 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
783 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
785 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
786 "NetDev '%s' specified twice, ignoring.", name
);
793 int config_parse_domains(
795 const char *filename
,
798 unsigned section_line
,
813 if (isempty(rvalue
)) {
814 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
815 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
821 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
825 r
= extract_first_word(&p
, &w
, NULL
, 0);
827 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
828 "Failed to extract search or route domain, ignoring: %s", rvalue
);
834 is_route
= w
[0] == '~';
835 domain
= is_route
? w
+ 1 : w
;
837 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
838 /* If the root domain appears as is, or the special token "*" is found, we'll
839 * consider this as routing domain, unconditionally. */
841 domain
= "."; /* make sure we don't allow empty strings, thus write the root
844 r
= dns_name_normalize(domain
, 0, &normalized
);
846 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
847 "'%s' is not a valid domain name, ignoring.", domain
);
853 if (is_localhost(domain
)) {
854 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
855 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
861 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
862 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
866 r
= ordered_set_put_strdup(*set
, domain
);
874 int config_parse_ipv6token(
876 const char *filename
,
879 unsigned section_line
,
886 union in_addr_union buffer
;
887 struct in6_addr
*token
= data
;
895 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
897 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
898 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
902 if (in_addr_is_null(AF_INET6
, &buffer
)) {
903 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
904 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
908 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
909 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
910 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
919 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
920 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
921 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
922 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
925 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
926 IPV6_PRIVACY_EXTENSIONS_YES
);
928 int config_parse_ipv6_privacy_extensions(
930 const char *filename
,
933 unsigned section_line
,
940 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
945 assert(ipv6_privacy_extensions
);
947 s
= ipv6_privacy_extensions_from_string(rvalue
);
949 if (streq(rvalue
, "kernel"))
950 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
952 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
953 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
958 *ipv6_privacy_extensions
= s
;
963 int config_parse_hostname(
965 const char *filename
,
968 unsigned section_line
,
975 _cleanup_free_
char *hn
= NULL
;
976 char **hostname
= data
;
983 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
987 if (!hostname_is_valid(hn
, false)) {
988 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
989 "Hostname is not valid, ignoring assignment: %s", rvalue
);
993 r
= dns_name_is_valid(hn
);
995 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
996 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1000 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1001 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1005 return free_and_replace(*hostname
, hn
);
1008 int config_parse_timezone(
1010 const char *filename
,
1012 const char *section
,
1013 unsigned section_line
,
1020 _cleanup_free_
char *tz
= NULL
;
1021 char **datap
= data
;
1028 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1032 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1033 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1034 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1038 return free_and_replace(*datap
, tz
);
1041 int config_parse_dns(
1043 const char *filename
,
1045 const char *section
,
1046 unsigned section_line
,
1053 Network
*n
= userdata
;
1061 _cleanup_free_
char *w
= NULL
;
1062 union in_addr_union a
;
1063 struct in_addr_data
*m
;
1066 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1070 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1071 "Invalid syntax, ignoring: %s", rvalue
);
1077 r
= in_addr_from_string_auto(w
, &family
, &a
);
1079 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1080 "Failed to parse dns server address, ignoring: %s", w
);
1084 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1088 m
[n
->n_dns
++] = (struct in_addr_data
) {
1099 int config_parse_dnssec_negative_trust_anchors(
1101 const char *filename
,
1103 const char *section
,
1104 unsigned section_line
,
1111 const char *p
= rvalue
;
1119 if (isempty(rvalue
)) {
1120 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1125 _cleanup_free_
char *w
= NULL
;
1127 r
= extract_first_word(&p
, &w
, NULL
, 0);
1129 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1130 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1136 r
= dns_name_is_valid(w
);
1138 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1139 "%s is not a valid domain name, ignoring.", w
);
1143 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1147 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1157 int config_parse_ntp(
1159 const char *filename
,
1161 const char *section
,
1162 unsigned section_line
,
1176 if (isempty(rvalue
)) {
1182 _cleanup_free_
char *w
= NULL
;
1184 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1188 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1189 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1195 r
= dns_name_is_valid_or_address(w
);
1197 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1198 "%s is not a valid domain name or IP address, ignoring.", w
);
1202 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1203 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1204 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1205 MAX_NTP_SERVERS
, w
);
1209 r
= strv_consume(l
, TAKE_PTR(w
));
1217 int config_parse_required_for_online(
1219 const char *filename
,
1221 const char *section
,
1222 unsigned section_line
,
1229 Network
*network
= data
;
1230 LinkOperationalState s
;
1231 bool required
= true;
1234 if (isempty(rvalue
)) {
1235 network
->required_for_online
= true;
1236 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1240 s
= link_operstate_from_string(rvalue
);
1242 r
= parse_boolean(rvalue
);
1244 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1245 "Failed to parse %s= setting, ignoring assignment: %s",
1251 s
= LINK_OPERSTATE_DEGRADED
;
1254 network
->required_for_online
= required
;
1255 network
->required_operstate_for_online
= s
;
1260 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1261 "Failed to parse KeepConfiguration= setting");
1263 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1264 [KEEP_CONFIGURATION_NO
] = "no",
1265 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1266 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1267 [KEEP_CONFIGURATION_STATIC
] = "static",
1268 [KEEP_CONFIGURATION_YES
] = "yes",
1271 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);