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 "networkd-dhcp-server.h"
15 #include "network-internal.h"
16 #include "networkd-manager.h"
17 #include "networkd-network.h"
18 #include "parse-util.h"
20 #include "socket-util.h"
21 #include "stat-util.h"
22 #include "string-table.h"
23 #include "string-util.h"
27 /* Let's assume that anything above this number is a user misconfiguration. */
28 #define MAX_NTP_SERVERS 128
30 /* Set defaults following RFC7844 */
31 void network_apply_anonymize_if_set(Network
*network
) {
32 if (!network
->dhcp_anonymize
)
35 SHOULD NOT send the Host Name option */
36 network
->dhcp_send_hostname
= false;
37 /* RFC7844 section 3.:
38 MAY contain the Client Identifier option
40 clients MUST use client identifiers based solely
41 on the link-layer address */
42 /* NOTE: Using MAC, as it does not reveal extra information,
43 * and some servers might not answer if this option is not sent */
44 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
46 SHOULD NOT use the Vendor Class Identifier option */
47 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
48 /* RFC7844 section 3.6.:
49 The client intending to protect its privacy SHOULD only request a
50 minimal number of options in the PRL and SHOULD also randomly shuffle
51 the ordering of option codes in the PRL. If this random ordering
52 cannot be implemented, the client MAY order the option codes in the
53 PRL by option code number (lowest to highest).
55 /* NOTE: dhcp_use_mtu is false by default,
56 * though it was not initiallized to any value in network_load_one.
57 * Maybe there should be another var called *send*?
58 * (to use the MTU sent by the server but to do not send
59 * the option in the PRL). */
60 network
->dhcp_use_mtu
= false;
61 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
62 * but this is needed to use them. */
63 network
->dhcp_use_routes
= true;
64 /* RFC7844 section 3.6.
65 * same comments as previous option */
66 network
->dhcp_use_timezone
= false;
69 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
70 const char *kind_string
;
74 /* For test-networkd-conf, the check must be earlier than the assertions. */
79 assert(network
->manager
);
80 assert(network
->filename
);
83 if (kind
== _NETDEV_KIND_TUNNEL
)
84 kind_string
= "tunnel";
86 kind_string
= netdev_kind_to_string(kind
);
88 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
89 "%s: Invalid NetDev kind of %s, ignoring assignment.",
90 network
->filename
, name
);
93 r
= netdev_get(network
->manager
, name
, &netdev
);
95 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
96 network
->filename
, name
);
98 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
105 NETDEV_KIND_IP6GRETAP
,
109 NETDEV_KIND_ERSPAN
)))
110 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
111 "%s: NetDev %s is not a %s, ignoring assignment",
112 network
->filename
, name
, kind_string
);
114 *ret_netdev
= netdev_ref(netdev
);
118 static int network_resolve_stacked_netdevs(Network
*network
) {
125 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
126 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
128 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
132 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
136 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
138 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
139 network
->filename
, (const char *) name
);
147 int network_verify(Network
*network
) {
148 RoutePrefix
*route_prefix
, *route_prefix_next
;
149 RoutingPolicyRule
*rule
, *rule_next
;
150 Neighbor
*neighbor
, *neighbor_next
;
151 AddressLabel
*label
, *label_next
;
152 NextHop
*nexthop
, *nextnop_next
;
153 Address
*address
, *address_next
;
154 Prefix
*prefix
, *prefix_next
;
155 Route
*route
, *route_next
;
156 FdbEntry
*fdb
, *fdb_next
;
159 assert(network
->filename
);
161 if (set_isempty(network
->match_mac
) && strv_isempty(network
->match_path
) &&
162 strv_isempty(network
->match_driver
) && strv_isempty(network
->match_type
) &&
163 strv_isempty(network
->match_name
) && strv_isempty(network
->match_property
) &&
164 strv_isempty(network
->match_ssid
) && !network
->conditions
)
165 log_warning("%s: No valid settings found in the [Match] section. "
166 "The file will match all interfaces. "
167 "If that is intended, please add Name=* in the [Match] section.",
170 /* skip out early if configuration does not match the environment */
171 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
172 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
173 "%s: Conditions in the file do not match the system environment, skipping.",
176 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
177 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
178 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
179 (void) network_resolve_stacked_netdevs(network
);
181 /* Free unnecessary entries. */
182 network
->bond_name
= mfree(network
->bond_name
);
183 network
->bridge_name
= mfree(network
->bridge_name
);
184 network
->vrf_name
= mfree(network
->vrf_name
);
185 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
188 /* Bonding slave does not support addressing. */
189 if (network
->ipv6_accept_ra
> 0) {
190 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
192 network
->ipv6_accept_ra
= 0;
194 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
195 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
197 network
->link_local
= ADDRESS_FAMILY_NO
;
199 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
200 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
202 network
->dhcp
= ADDRESS_FAMILY_NO
;
204 if (network
->dhcp_server
) {
205 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
207 network
->dhcp_server
= false;
209 if (network
->n_static_addresses
> 0) {
210 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
212 while ((address
= network
->static_addresses
))
213 address_free(address
);
215 if (network
->n_static_routes
> 0) {
216 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
218 while ((route
= network
->static_routes
))
223 if (network
->link_local
< 0)
224 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
226 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
227 if (network
->ipv6_accept_ra
> 0) {
228 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
229 "Disabling IPv6AcceptRA=.", network
->filename
);
230 network
->ipv6_accept_ra
= false;
233 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
234 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
235 "Disabling DHCPv6 client.", network
->filename
);
236 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
239 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
240 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
241 "Disabling IPv6PrefixDelegation=.", network
->filename
);
242 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
246 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
247 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
248 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
249 "Disabling the fallback assignment.", network
->filename
);
250 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
253 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
254 network
->ipv6_accept_ra
= false;
256 /* IPMasquerade=yes implies IPForward=yes */
257 if (network
->ip_masquerade
)
258 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
260 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
261 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
262 "Disabling UseMTU=.", network
->filename
);
263 network
->dhcp_use_mtu
= false;
266 if (network
->dhcp_critical
>= 0) {
267 if (network
->keep_configuration
>= 0)
268 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
269 "Ignoring CriticalConnection=.", network
->filename
);
270 else if (network
->dhcp_critical
)
271 /* CriticalConnection=yes also preserve foreign static configurations. */
272 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
274 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
277 if (network
->keep_configuration
< 0)
278 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
280 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
281 if (address_section_verify(address
) < 0)
282 address_free(address
);
284 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
285 if (route_section_verify(route
, network
) < 0)
288 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
289 if (nexthop_section_verify(nexthop
) < 0)
290 nexthop_free(nexthop
);
292 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
293 if (section_is_invalid(fdb
->section
))
296 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
297 if (neighbor_section_verify(neighbor
) < 0)
298 neighbor_free(neighbor
);
300 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
301 if (section_is_invalid(label
->section
))
302 address_label_free(label
);
304 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
305 if (section_is_invalid(prefix
->section
))
308 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
309 if (section_is_invalid(route_prefix
->section
))
310 route_prefix_free(route_prefix
);
312 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
313 if (routing_policy_rule_section_verify(rule
) < 0)
314 routing_policy_rule_free(rule
);
319 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
320 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
321 _cleanup_(network_unrefp
) Network
*network
= NULL
;
322 _cleanup_fclose_
FILE *file
= NULL
;
323 const char *dropin_dirname
;
330 file
= fopen(filename
, "re");
338 if (null_or_empty_fd(fileno(file
))) {
339 log_debug("Skipping empty file: %s", filename
);
343 fname
= strdup(filename
);
347 name
= strdup(basename(filename
));
351 d
= strrchr(name
, '.');
357 dropin_dirname
= strjoina(name
, ".network.d");
359 network
= new(Network
, 1);
363 *network
= (Network
) {
364 .filename
= TAKE_PTR(fname
),
365 .name
= TAKE_PTR(name
),
370 .required_for_online
= true,
371 .required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
,
372 .dhcp
= ADDRESS_FAMILY_NO
,
374 .dhcp_use_ntp
= true,
375 .dhcp_use_sip
= true,
376 .dhcp_use_dns
= true,
377 .dhcp_use_hostname
= true,
378 .dhcp_use_routes
= true,
379 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
380 .dhcp_send_hostname
= true,
381 .dhcp_send_release
= true,
382 /* To enable/disable RFC7844 Anonymity Profiles */
383 .dhcp_anonymize
= false,
384 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
385 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
386 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
387 .dhcp_route_table
= RT_TABLE_MAIN
,
388 .dhcp_route_table_set
= false,
389 /* NOTE: from man: UseMTU=... Defaults to false*/
390 .dhcp_use_mtu
= false,
391 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
392 .dhcp_use_timezone
= false,
393 .rapid_commit
= true,
395 .dhcp6_use_ntp
= true,
396 .dhcp6_use_dns
= true,
398 .dhcp_server_emit_dns
= true,
399 .dhcp_server_emit_ntp
= true,
400 .dhcp_server_emit_sip
= true,
401 .dhcp_server_emit_router
= true,
402 .dhcp_server_emit_timezone
= true,
404 .router_emit_dns
= true,
405 .router_emit_domains
= true,
410 .allow_port_to_be_root
= -1,
412 .multicast_flood
= -1,
413 .multicast_to_unicast
= -1,
414 .neighbor_suppression
= -1,
416 .bridge_proxy_arp
= -1,
417 .bridge_proxy_arp_wifi
= -1,
418 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
419 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
421 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
423 .dns_default_route
= -1,
424 .llmnr
= RESOLVE_SUPPORT_YES
,
425 .mdns
= RESOLVE_SUPPORT_NO
,
426 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
427 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
429 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
430 .link_local
= _ADDRESS_FAMILY_INVALID
,
432 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
433 .ipv6_accept_ra
= -1,
434 .ipv6_dad_transmits
= -1,
435 .ipv6_hop_limit
= -1,
436 .ipv6_proxy_ndp
= -1,
437 .duid
.type
= _DUID_TYPE_INVALID
,
442 .ipv6_accept_ra_use_dns
= true,
443 .ipv6_accept_ra_use_autonomous_prefix
= true,
444 .ipv6_accept_ra_use_onlink_prefix
= true,
445 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
446 .ipv6_accept_ra_route_table_set
= false,
448 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
450 .can_triple_sampling
= -1,
451 .ip_service_type
= -1,
454 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
461 "RoutingPolicyRule\0"
464 "DHCP\0" /* compat */
469 "IPv6NDPProxyAddress\0"
473 "IPv6PrefixDelegation\0"
476 "TrafficControlQueueingDiscipline\0"
478 config_item_perf_lookup
, network_network_gperf_lookup
,
479 CONFIG_PARSE_WARN
, network
);
483 network_apply_anonymize_if_set(network
);
485 r
= network_add_ipv4ll_route(network
);
487 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
489 r
= network_add_default_route_on_device(network
);
491 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
495 if (stat(filename
, &stats
) < 0)
497 network
->timestamp
= timespec_load(&stats
.st_mtim
);
499 if (network_verify(network
) < 0)
500 /* Ignore .network files that do not match the conditions. */
503 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
507 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
515 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
516 _cleanup_strv_free_
char **files
= NULL
;
522 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
524 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
526 return log_error_errno(r
, "Failed to enumerate network files: %m");
528 STRV_FOREACH(f
, files
) {
529 r
= network_load_one(manager
, networks
, *f
);
531 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
537 int network_reload(Manager
*manager
) {
538 OrderedHashmap
*new_networks
= NULL
;
545 r
= network_load(manager
, &new_networks
);
549 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
550 r
= network_get_by_name(manager
, n
->name
, &old
);
552 continue; /* The .network file is new. */
554 if (n
->timestamp
!= old
->timestamp
)
555 continue; /* The .network file is modified. */
557 if (!streq(n
->filename
, old
->filename
))
560 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
568 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
569 manager
->networks
= new_networks
;
574 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
579 static Network
*network_free(Network
*network
) {
580 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
581 RoutePrefix
*route_prefix
;
582 RoutingPolicyRule
*rule
;
594 free(network
->filename
);
596 set_free_free(network
->match_mac
);
597 strv_free(network
->match_path
);
598 strv_free(network
->match_driver
);
599 strv_free(network
->match_type
);
600 strv_free(network
->match_name
);
601 strv_free(network
->match_property
);
602 strv_free(network
->match_wlan_iftype
);
603 strv_free(network
->match_ssid
);
604 set_free_free(network
->match_bssid
);
605 condition_free_list(network
->conditions
);
607 free(network
->description
);
608 free(network
->dhcp_vendor_class_identifier
);
609 strv_free(network
->dhcp_user_class
);
610 free(network
->dhcp_hostname
);
611 set_free(network
->dhcp_black_listed_ip
);
612 set_free(network
->dhcp_request_options
);
615 strv_free(network
->ntp
);
617 strv_free(network
->sip
);
618 ordered_set_free_free(network
->search_domains
);
619 ordered_set_free_free(network
->route_domains
);
620 strv_free(network
->bind_carrier
);
622 ordered_set_free_free(network
->router_search_domains
);
623 free(network
->router_dns
);
624 set_free_free(network
->ndisc_black_listed_prefix
);
626 free(network
->bridge_name
);
627 free(network
->bond_name
);
628 free(network
->vrf_name
);
629 hashmap_free_free_key(network
->stacked_netdev_names
);
630 netdev_unref(network
->bridge
);
631 netdev_unref(network
->bond
);
632 netdev_unref(network
->vrf
);
633 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
635 while ((route
= network
->static_routes
))
638 while ((nexthop
= network
->static_nexthops
))
639 nexthop_free(nexthop
);
641 while ((address
= network
->static_addresses
))
642 address_free(address
);
644 while ((fdb_entry
= network
->static_fdb_entries
))
645 fdb_entry_free(fdb_entry
);
647 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
648 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
650 while ((neighbor
= network
->neighbors
))
651 neighbor_free(neighbor
);
653 while ((label
= network
->address_labels
))
654 address_label_free(label
);
656 while ((prefix
= network
->static_prefixes
))
659 while ((route_prefix
= network
->static_route_prefixes
))
660 route_prefix_free(route_prefix
);
662 while ((rule
= network
->rules
))
663 routing_policy_rule_free(rule
);
665 hashmap_free(network
->addresses_by_section
);
666 hashmap_free(network
->routes_by_section
);
667 hashmap_free(network
->nexthops_by_section
);
668 hashmap_free(network
->fdb_entries_by_section
);
669 hashmap_free(network
->neighbors_by_section
);
670 hashmap_free(network
->address_labels_by_section
);
671 hashmap_free(network
->prefixes_by_section
);
672 hashmap_free(network
->route_prefixes_by_section
);
673 hashmap_free(network
->rules_by_section
);
674 ordered_hashmap_free_with_destructor(network
->qdiscs_by_section
, qdisc_free
);
676 if (network
->manager
&&
677 network
->manager
->duids_requesting_uuid
)
678 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
682 free(network
->dhcp_server_timezone
);
683 free(network
->dhcp_server_dns
);
684 free(network
->dhcp_server_ntp
);
685 free(network
->dhcp_server_sip
);
687 set_free_free(network
->dnssec_negative_trust_anchors
);
689 ordered_hashmap_free(network
->dhcp_send_options
);
690 ordered_hashmap_free(network
->dhcp_server_options
);
692 return mfree(network
);
695 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
697 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
704 network
= ordered_hashmap_get(manager
->networks
, name
);
713 int network_get(Manager
*manager
, sd_device
*device
,
714 const char *ifname
, const struct ether_addr
*address
,
715 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
723 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
724 if (net_match_config(network
->match_mac
, network
->match_path
, network
->match_driver
,
725 network
->match_type
, network
->match_name
, network
->match_property
,
726 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
727 device
, address
, ifname
, wlan_iftype
, ssid
, bssid
)) {
728 if (network
->match_name
&& device
) {
730 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
732 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
733 (void) safe_atou8(attr
, &name_assign_type
);
735 if (name_assign_type
== NET_NAME_ENUM
)
736 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
737 ifname
, network
->filename
);
739 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
741 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
752 int network_apply(Network
*network
, Link
*link
) {
756 link
->network
= network_ref(network
);
758 if (network
->n_dns
> 0 ||
759 !strv_isempty(network
->ntp
) ||
760 !ordered_set_isempty(network
->search_domains
) ||
761 !ordered_set_isempty(network
->route_domains
))
767 bool network_has_static_ipv6_configurations(Network
*network
) {
775 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
776 if (address
->family
== AF_INET6
)
779 LIST_FOREACH(routes
, route
, network
->static_routes
)
780 if (route
->family
== AF_INET6
)
783 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
784 if (fdb
->family
== AF_INET6
)
787 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
788 if (neighbor
->family
== AF_INET6
)
791 if (!LIST_IS_EMPTY(network
->address_labels
))
794 if (!LIST_IS_EMPTY(network
->static_prefixes
))
800 int config_parse_stacked_netdev(const char *unit
,
801 const char *filename
,
804 unsigned section_line
,
810 _cleanup_free_
char *name
= NULL
;
811 NetDevKind kind
= ltype
;
820 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
821 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
822 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
825 if (!ifname_valid(rvalue
)) {
826 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
827 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
831 name
= strdup(rvalue
);
835 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
839 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
841 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
842 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
844 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
845 "NetDev '%s' specified twice, ignoring.", name
);
852 int config_parse_domains(
854 const char *filename
,
857 unsigned section_line
,
872 if (isempty(rvalue
)) {
873 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
874 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
880 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
884 r
= extract_first_word(&p
, &w
, NULL
, 0);
886 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
887 "Failed to extract search or route domain, ignoring: %s", rvalue
);
893 is_route
= w
[0] == '~';
894 domain
= is_route
? w
+ 1 : w
;
896 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
897 /* If the root domain appears as is, or the special token "*" is found, we'll
898 * consider this as routing domain, unconditionally. */
900 domain
= "."; /* make sure we don't allow empty strings, thus write the root
903 r
= dns_name_normalize(domain
, 0, &normalized
);
905 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
906 "'%s' is not a valid domain name, ignoring.", domain
);
912 if (is_localhost(domain
)) {
913 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
914 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
920 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
921 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
925 r
= ordered_set_put_strdup(*set
, domain
);
933 int config_parse_ipv6token(
935 const char *filename
,
938 unsigned section_line
,
945 union in_addr_union buffer
;
946 struct in6_addr
*token
= data
;
954 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
956 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
957 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
961 if (in_addr_is_null(AF_INET6
, &buffer
)) {
962 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
963 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
967 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
968 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
969 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
978 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
979 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
980 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
981 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
984 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
985 IPV6_PRIVACY_EXTENSIONS_YES
);
987 int config_parse_ipv6_privacy_extensions(
989 const char *filename
,
992 unsigned section_line
,
999 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1004 assert(ipv6_privacy_extensions
);
1006 s
= ipv6_privacy_extensions_from_string(rvalue
);
1008 if (streq(rvalue
, "kernel"))
1009 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1011 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1012 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1017 *ipv6_privacy_extensions
= s
;
1022 int config_parse_hostname(
1024 const char *filename
,
1026 const char *section
,
1027 unsigned section_line
,
1034 _cleanup_free_
char *hn
= NULL
;
1035 char **hostname
= data
;
1042 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1046 if (!hostname_is_valid(hn
, false)) {
1047 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1048 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1052 r
= dns_name_is_valid(hn
);
1054 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1055 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1059 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1060 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1064 return free_and_replace(*hostname
, hn
);
1067 int config_parse_timezone(
1069 const char *filename
,
1071 const char *section
,
1072 unsigned section_line
,
1079 _cleanup_free_
char *tz
= NULL
;
1080 char **datap
= data
;
1087 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1091 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1092 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1093 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1097 return free_and_replace(*datap
, tz
);
1100 int config_parse_dns(
1102 const char *filename
,
1104 const char *section
,
1105 unsigned section_line
,
1112 Network
*n
= userdata
;
1120 _cleanup_free_
char *w
= NULL
;
1121 union in_addr_union a
;
1122 struct in_addr_data
*m
;
1125 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1129 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1130 "Invalid syntax, ignoring: %s", rvalue
);
1136 r
= in_addr_from_string_auto(w
, &family
, &a
);
1138 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1139 "Failed to parse dns server address, ignoring: %s", w
);
1143 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1147 m
[n
->n_dns
++] = (struct in_addr_data
) {
1158 int config_parse_dnssec_negative_trust_anchors(
1160 const char *filename
,
1162 const char *section
,
1163 unsigned section_line
,
1170 const char *p
= rvalue
;
1178 if (isempty(rvalue
)) {
1179 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1184 _cleanup_free_
char *w
= NULL
;
1186 r
= extract_first_word(&p
, &w
, NULL
, 0);
1188 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1189 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1195 r
= dns_name_is_valid(w
);
1197 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1198 "%s is not a valid domain name, ignoring.", w
);
1202 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1206 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1216 int config_parse_ntp(
1218 const char *filename
,
1220 const char *section
,
1221 unsigned section_line
,
1235 if (isempty(rvalue
)) {
1241 _cleanup_free_
char *w
= NULL
;
1243 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1247 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1248 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1254 r
= dns_name_is_valid_or_address(w
);
1256 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1257 "%s is not a valid domain name or IP address, ignoring.", w
);
1261 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1262 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1263 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1264 MAX_NTP_SERVERS
, w
);
1268 r
= strv_consume(l
, TAKE_PTR(w
));
1276 int config_parse_required_for_online(
1278 const char *filename
,
1280 const char *section
,
1281 unsigned section_line
,
1288 Network
*network
= data
;
1289 LinkOperationalState s
;
1290 bool required
= true;
1293 if (isempty(rvalue
)) {
1294 network
->required_for_online
= true;
1295 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1299 s
= link_operstate_from_string(rvalue
);
1301 r
= parse_boolean(rvalue
);
1303 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1304 "Failed to parse %s= setting, ignoring assignment: %s",
1310 s
= LINK_OPERSTATE_DEGRADED
;
1313 network
->required_for_online
= required
;
1314 network
->required_operstate_for_online
= s
;
1319 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1320 "Failed to parse KeepConfiguration= setting");
1322 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1323 [KEEP_CONFIGURATION_NO
] = "no",
1324 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1325 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1326 [KEEP_CONFIGURATION_STATIC
] = "static",
1327 [KEEP_CONFIGURATION_YES
] = "yes",
1330 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);