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"
28 /* Let's assume that anything above this number is a user misconfiguration. */
29 #define MAX_NTP_SERVERS 128
31 /* Set defaults following RFC7844 */
32 void network_apply_anonymize_if_set(Network
*network
) {
33 if (!network
->dhcp_anonymize
)
36 SHOULD NOT send the Host Name option */
37 network
->dhcp_send_hostname
= false;
38 /* RFC7844 section 3.:
39 MAY contain the Client Identifier option
41 clients MUST use client identifiers based solely
42 on the link-layer address */
43 /* NOTE: Using MAC, as it does not reveal extra information,
44 * and some servers might not answer if this option is not sent */
45 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
47 SHOULD NOT use the Vendor Class Identifier option */
48 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
49 /* RFC7844 section 3.6.:
50 The client intending to protect its privacy SHOULD only request a
51 minimal number of options in the PRL and SHOULD also randomly shuffle
52 the ordering of option codes in the PRL. If this random ordering
53 cannot be implemented, the client MAY order the option codes in the
54 PRL by option code number (lowest to highest).
56 /* NOTE: dhcp_use_mtu is false by default,
57 * though it was not initiallized to any value in network_load_one.
58 * Maybe there should be another var called *send*?
59 * (to use the MTU sent by the server but to do not send
60 * the option in the PRL). */
61 network
->dhcp_use_mtu
= false;
62 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
63 * but this is needed to use them. */
64 network
->dhcp_use_routes
= true;
65 /* RFC7844 section 3.6.
66 * same comments as previous option */
67 network
->dhcp_use_timezone
= false;
70 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
71 const char *kind_string
;
75 /* For test-networkd-conf, the check must be earlier than the assertions. */
80 assert(network
->manager
);
81 assert(network
->filename
);
84 if (kind
== _NETDEV_KIND_TUNNEL
)
85 kind_string
= "tunnel";
87 kind_string
= netdev_kind_to_string(kind
);
89 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
90 "%s: Invalid NetDev kind of %s, ignoring assignment.",
91 network
->filename
, name
);
94 r
= netdev_get(network
->manager
, name
, &netdev
);
96 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
97 network
->filename
, name
);
99 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
106 NETDEV_KIND_IP6GRETAP
,
110 NETDEV_KIND_ERSPAN
)))
111 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
112 "%s: NetDev %s is not a %s, ignoring assignment",
113 network
->filename
, name
, kind_string
);
115 *ret_netdev
= netdev_ref(netdev
);
119 static int network_resolve_stacked_netdevs(Network
*network
) {
126 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
127 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
129 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
133 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
137 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
139 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
140 network
->filename
, (const char *) name
);
148 int network_verify(Network
*network
) {
149 RoutePrefix
*route_prefix
, *route_prefix_next
;
150 RoutingPolicyRule
*rule
, *rule_next
;
151 Neighbor
*neighbor
, *neighbor_next
;
152 AddressLabel
*label
, *label_next
;
153 NextHop
*nexthop
, *nextnop_next
;
154 Address
*address
, *address_next
;
155 Prefix
*prefix
, *prefix_next
;
156 Route
*route
, *route_next
;
157 FdbEntry
*fdb
, *fdb_next
;
162 assert(network
->filename
);
164 if (set_isempty(network
->match_mac
) && set_isempty(network
->match_permanent_mac
) &&
165 strv_isempty(network
->match_path
) && strv_isempty(network
->match_driver
) &&
166 strv_isempty(network
->match_type
) && strv_isempty(network
->match_name
) &&
167 strv_isempty(network
->match_property
) && strv_isempty(network
->match_ssid
) && !network
->conditions
)
168 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
169 "%s: No valid settings found in the [Match] section, ignoring file. "
170 "To match all interfaces, add Name=* in the [Match] section.",
173 /* skip out early if configuration does not match the environment */
174 if (!condition_test_list(network
->conditions
, 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 (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
230 if (network
->ipv6_accept_ra
> 0) {
231 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
232 "Disabling IPv6AcceptRA=.", network
->filename
);
233 network
->ipv6_accept_ra
= false;
236 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
237 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
238 "Disabling DHCPv6 client.", network
->filename
);
239 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
242 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
243 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
244 "Disabling IPv6PrefixDelegation=.", network
->filename
);
245 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
249 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
250 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
251 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
252 "Disabling the fallback assignment.", network
->filename
);
253 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
256 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
257 network
->ipv6_accept_ra
= false;
259 /* IPMasquerade=yes implies IPForward=yes */
260 if (network
->ip_masquerade
)
261 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
263 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
264 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
265 "Disabling UseMTU=.", network
->filename
);
266 network
->dhcp_use_mtu
= false;
269 if (network
->dhcp_critical
>= 0) {
270 if (network
->keep_configuration
>= 0)
271 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
272 "Ignoring CriticalConnection=.", network
->filename
);
273 else if (network
->dhcp_critical
)
274 /* CriticalConnection=yes also preserve foreign static configurations. */
275 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
277 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
280 if (network
->keep_configuration
< 0)
281 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
283 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
284 if (address_section_verify(address
) < 0)
285 address_free(address
);
287 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
288 if (route_section_verify(route
, network
) < 0)
291 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
292 if (nexthop_section_verify(nexthop
) < 0)
293 nexthop_free(nexthop
);
295 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
296 if (section_is_invalid(fdb
->section
))
299 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
300 if (neighbor_section_verify(neighbor
) < 0)
301 neighbor_free(neighbor
);
303 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
304 if (section_is_invalid(label
->section
))
305 address_label_free(label
);
307 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
308 if (section_is_invalid(prefix
->section
))
311 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
312 if (section_is_invalid(route_prefix
->section
))
313 route_prefix_free(route_prefix
);
315 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
316 if (routing_policy_rule_section_verify(rule
) < 0)
317 routing_policy_rule_free(rule
);
319 bool has_root
= false, has_clsact
= false;
320 ORDERED_HASHMAP_FOREACH(tc
, network
->tc_by_section
, i
)
321 if (traffic_control_section_verify(tc
, &has_root
, &has_clsact
) < 0)
322 traffic_control_free(tc
);
327 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
328 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
329 _cleanup_(network_unrefp
) Network
*network
= NULL
;
330 _cleanup_fclose_
FILE *file
= NULL
;
331 const char *dropin_dirname
;
338 file
= fopen(filename
, "re");
346 if (null_or_empty_fd(fileno(file
))) {
347 log_debug("Skipping empty file: %s", filename
);
351 fname
= strdup(filename
);
355 name
= strdup(basename(filename
));
359 d
= strrchr(name
, '.');
365 dropin_dirname
= strjoina(name
, ".network.d");
367 network
= new(Network
, 1);
371 *network
= (Network
) {
372 .filename
= TAKE_PTR(fname
),
373 .name
= TAKE_PTR(name
),
378 .required_for_online
= true,
379 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
380 .dhcp
= ADDRESS_FAMILY_NO
,
382 .dhcp_use_ntp
= true,
383 .dhcp_use_sip
= true,
384 .dhcp_use_dns
= true,
385 .dhcp_use_hostname
= true,
386 .dhcp_use_routes
= true,
387 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
388 .dhcp_send_hostname
= true,
389 .dhcp_send_release
= true,
390 /* To enable/disable RFC7844 Anonymity Profiles */
391 .dhcp_anonymize
= false,
392 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
393 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
394 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
395 .dhcp_route_table
= RT_TABLE_MAIN
,
396 .dhcp_route_table_set
= false,
397 /* NOTE: from man: UseMTU=... Defaults to false*/
398 .dhcp_use_mtu
= false,
399 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
400 .dhcp_use_timezone
= false,
401 .rapid_commit
= true,
403 .dhcp6_use_ntp
= true,
404 .dhcp6_use_dns
= true,
406 .dhcp_server_emit_dns
= true,
407 .dhcp_server_emit_ntp
= true,
408 .dhcp_server_emit_sip
= true,
409 .dhcp_server_emit_router
= true,
410 .dhcp_server_emit_timezone
= true,
412 .router_emit_dns
= true,
413 .router_emit_domains
= true,
418 .allow_port_to_be_root
= -1,
420 .multicast_flood
= -1,
421 .multicast_to_unicast
= -1,
422 .neighbor_suppression
= -1,
424 .bridge_proxy_arp
= -1,
425 .bridge_proxy_arp_wifi
= -1,
426 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
427 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
429 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
431 .dns_default_route
= -1,
432 .llmnr
= RESOLVE_SUPPORT_YES
,
433 .mdns
= RESOLVE_SUPPORT_NO
,
434 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
435 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
437 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
438 .link_local
= _ADDRESS_FAMILY_INVALID
,
440 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
441 .ipv6_accept_ra
= -1,
442 .ipv6_dad_transmits
= -1,
443 .ipv6_hop_limit
= -1,
444 .ipv6_proxy_ndp
= -1,
445 .duid
.type
= _DUID_TYPE_INVALID
,
450 .ipv6_accept_ra_use_dns
= true,
451 .ipv6_accept_ra_use_autonomous_prefix
= true,
452 .ipv6_accept_ra_use_onlink_prefix
= true,
453 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
454 .ipv6_accept_ra_route_table_set
= false,
455 .ipv6_accept_ra_start_dhcp6_client
= true,
457 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
459 .can_triple_sampling
= -1,
460 .can_termination
= -1,
461 .ip_service_type
= -1,
464 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
471 "RoutingPolicyRule\0"
474 "DHCP\0" /* compat */
479 "IPv6NDPProxyAddress\0"
483 "IPv6PrefixDelegation\0"
486 "TrafficControlQueueingDiscipline\0"
493 "FairQueueingControlledDelay\0"
494 "GenericRandomEarlyDetection\0"
495 "HierarchyTokenBucket\0"
496 "HierarchyTokenBucketClass\0"
498 "StochasticFairBlue\0"
499 "StochasticFairnessQueueing\0"
500 "TokenBucketFilter\0"
501 "TrivialLinkEqualizer\0",
502 config_item_perf_lookup
, network_network_gperf_lookup
,
503 CONFIG_PARSE_WARN
, network
);
507 network_apply_anonymize_if_set(network
);
509 r
= network_add_ipv4ll_route(network
);
511 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
513 r
= network_add_default_route_on_device(network
);
515 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
519 if (stat(filename
, &stats
) < 0)
521 network
->timestamp
= timespec_load(&stats
.st_mtim
);
523 if (network_verify(network
) < 0)
524 /* Ignore .network files that do not match the conditions. */
527 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
531 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
539 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
540 _cleanup_strv_free_
char **files
= NULL
;
546 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
548 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
550 return log_error_errno(r
, "Failed to enumerate network files: %m");
552 STRV_FOREACH(f
, files
) {
553 r
= network_load_one(manager
, networks
, *f
);
555 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
561 int network_reload(Manager
*manager
) {
562 OrderedHashmap
*new_networks
= NULL
;
569 r
= network_load(manager
, &new_networks
);
573 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
574 r
= network_get_by_name(manager
, n
->name
, &old
);
576 continue; /* The .network file is new. */
578 if (n
->timestamp
!= old
->timestamp
)
579 continue; /* The .network file is modified. */
581 if (!streq(n
->filename
, old
->filename
))
584 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
592 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
593 manager
->networks
= new_networks
;
598 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
603 static Network
*network_free(Network
*network
) {
604 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
605 RoutePrefix
*route_prefix
;
606 RoutingPolicyRule
*rule
;
618 free(network
->filename
);
620 set_free_free(network
->match_mac
);
621 set_free_free(network
->match_permanent_mac
);
622 strv_free(network
->match_path
);
623 strv_free(network
->match_driver
);
624 strv_free(network
->match_type
);
625 strv_free(network
->match_name
);
626 strv_free(network
->match_property
);
627 strv_free(network
->match_wlan_iftype
);
628 strv_free(network
->match_ssid
);
629 set_free_free(network
->match_bssid
);
630 condition_free_list(network
->conditions
);
632 free(network
->description
);
633 free(network
->dhcp_vendor_class_identifier
);
634 strv_free(network
->dhcp_user_class
);
635 free(network
->dhcp_hostname
);
636 set_free(network
->dhcp_black_listed_ip
);
637 set_free(network
->dhcp_request_options
);
640 if (network
->dhcp_acd
)
641 sd_ipv4acd_unref(network
->dhcp_acd
);
643 strv_free(network
->ntp
);
645 strv_free(network
->sip
);
646 ordered_set_free_free(network
->search_domains
);
647 ordered_set_free_free(network
->route_domains
);
648 strv_free(network
->bind_carrier
);
650 ordered_set_free_free(network
->router_search_domains
);
651 free(network
->router_dns
);
652 set_free_free(network
->ndisc_black_listed_prefix
);
654 free(network
->bridge_name
);
655 free(network
->bond_name
);
656 free(network
->vrf_name
);
657 hashmap_free_free_key(network
->stacked_netdev_names
);
658 netdev_unref(network
->bridge
);
659 netdev_unref(network
->bond
);
660 netdev_unref(network
->vrf
);
661 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
663 while ((route
= network
->static_routes
))
666 while ((nexthop
= network
->static_nexthops
))
667 nexthop_free(nexthop
);
669 while ((address
= network
->static_addresses
))
670 address_free(address
);
672 while ((fdb_entry
= network
->static_fdb_entries
))
673 fdb_entry_free(fdb_entry
);
675 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
676 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
678 while ((neighbor
= network
->neighbors
))
679 neighbor_free(neighbor
);
681 while ((label
= network
->address_labels
))
682 address_label_free(label
);
684 while ((prefix
= network
->static_prefixes
))
687 while ((route_prefix
= network
->static_route_prefixes
))
688 route_prefix_free(route_prefix
);
690 while ((rule
= network
->rules
))
691 routing_policy_rule_free(rule
);
693 hashmap_free(network
->addresses_by_section
);
694 hashmap_free(network
->routes_by_section
);
695 hashmap_free(network
->nexthops_by_section
);
696 hashmap_free(network
->fdb_entries_by_section
);
697 hashmap_free(network
->neighbors_by_section
);
698 hashmap_free(network
->address_labels_by_section
);
699 hashmap_free(network
->prefixes_by_section
);
700 hashmap_free(network
->route_prefixes_by_section
);
701 hashmap_free(network
->rules_by_section
);
702 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
704 if (network
->manager
&&
705 network
->manager
->duids_requesting_uuid
)
706 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
710 free(network
->dhcp_server_timezone
);
711 free(network
->dhcp_server_dns
);
712 free(network
->dhcp_server_ntp
);
713 free(network
->dhcp_server_sip
);
715 set_free_free(network
->dnssec_negative_trust_anchors
);
717 ordered_hashmap_free(network
->dhcp_client_send_options
);
718 ordered_hashmap_free(network
->dhcp_server_send_options
);
719 ordered_hashmap_free(network
->ipv6_tokens
);
721 return mfree(network
);
724 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
726 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
733 network
= ordered_hashmap_get(manager
->networks
, name
);
742 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
743 const char *ifname
, char * const *alternative_names
,
744 const struct ether_addr
*address
, const struct ether_addr
*permanent_address
,
745 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
753 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
754 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
755 network
->match_path
, network
->match_driver
,
756 network
->match_type
, network
->match_name
, network
->match_property
,
757 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
758 iftype
, device
, address
, permanent_address
,
759 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
760 if (network
->match_name
&& device
) {
762 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
764 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
765 (void) safe_atou8(attr
, &name_assign_type
);
767 if (name_assign_type
== NET_NAME_ENUM
)
768 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
769 ifname
, network
->filename
);
771 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
773 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
784 int network_apply(Network
*network
, Link
*link
) {
788 link
->network
= network_ref(network
);
790 if (network
->n_dns
> 0 ||
791 !strv_isempty(network
->ntp
) ||
792 !ordered_set_isempty(network
->search_domains
) ||
793 !ordered_set_isempty(network
->route_domains
))
799 bool network_has_static_ipv6_configurations(Network
*network
) {
807 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
808 if (address
->family
== AF_INET6
)
811 LIST_FOREACH(routes
, route
, network
->static_routes
)
812 if (route
->family
== AF_INET6
)
815 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
816 if (fdb
->family
== AF_INET6
)
819 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
820 if (neighbor
->family
== AF_INET6
)
823 if (!LIST_IS_EMPTY(network
->address_labels
))
826 if (!LIST_IS_EMPTY(network
->static_prefixes
))
832 int config_parse_stacked_netdev(const char *unit
,
833 const char *filename
,
836 unsigned section_line
,
842 _cleanup_free_
char *name
= NULL
;
843 NetDevKind kind
= ltype
;
852 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
853 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
854 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
857 if (!ifname_valid(rvalue
)) {
858 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
859 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
863 name
= strdup(rvalue
);
867 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
871 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
873 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
874 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
876 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
877 "NetDev '%s' specified twice, ignoring.", name
);
884 int config_parse_domains(
886 const char *filename
,
889 unsigned section_line
,
904 if (isempty(rvalue
)) {
905 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
906 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
912 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
916 r
= extract_first_word(&p
, &w
, NULL
, 0);
918 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
919 "Failed to extract search or route domain, ignoring: %s", rvalue
);
925 is_route
= w
[0] == '~';
926 domain
= is_route
? w
+ 1 : w
;
928 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
929 /* If the root domain appears as is, or the special token "*" is found, we'll
930 * consider this as routing domain, unconditionally. */
932 domain
= "."; /* make sure we don't allow empty strings, thus write the root
935 r
= dns_name_normalize(domain
, 0, &normalized
);
937 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
938 "'%s' is not a valid domain name, ignoring.", domain
);
944 if (is_localhost(domain
)) {
945 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
946 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
952 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
953 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
957 r
= ordered_set_put_strdup(*set
, domain
);
965 int config_parse_ipv6token(
967 const char *filename
,
970 unsigned section_line
,
977 union in_addr_union buffer
;
978 struct in6_addr
*token
= data
;
986 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
988 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
989 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
993 if (in_addr_is_null(AF_INET6
, &buffer
)) {
994 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
995 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
999 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1000 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1001 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1005 *token
= buffer
.in6
;
1010 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1011 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1012 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1013 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1016 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1017 IPV6_PRIVACY_EXTENSIONS_YES
);
1019 int config_parse_ipv6_privacy_extensions(
1021 const char *filename
,
1023 const char *section
,
1024 unsigned section_line
,
1031 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1036 assert(ipv6_privacy_extensions
);
1038 s
= ipv6_privacy_extensions_from_string(rvalue
);
1040 if (streq(rvalue
, "kernel"))
1041 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1043 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1044 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1049 *ipv6_privacy_extensions
= s
;
1054 int config_parse_hostname(
1056 const char *filename
,
1058 const char *section
,
1059 unsigned section_line
,
1066 _cleanup_free_
char *hn
= NULL
;
1067 char **hostname
= data
;
1074 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1078 if (!hostname_is_valid(hn
, false)) {
1079 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1080 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1084 r
= dns_name_is_valid(hn
);
1086 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1087 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1091 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1092 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1096 return free_and_replace(*hostname
, hn
);
1099 int config_parse_timezone(
1101 const char *filename
,
1103 const char *section
,
1104 unsigned section_line
,
1111 _cleanup_free_
char *tz
= NULL
;
1112 char **datap
= data
;
1119 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1123 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1124 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1125 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1129 return free_and_replace(*datap
, tz
);
1132 int config_parse_dns(
1134 const char *filename
,
1136 const char *section
,
1137 unsigned section_line
,
1144 Network
*n
= userdata
;
1152 _cleanup_free_
char *w
= NULL
;
1153 union in_addr_union a
;
1154 struct in_addr_data
*m
;
1157 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1161 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1162 "Invalid syntax, ignoring: %s", rvalue
);
1168 r
= in_addr_from_string_auto(w
, &family
, &a
);
1170 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1171 "Failed to parse dns server address, ignoring: %s", w
);
1175 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1179 m
[n
->n_dns
++] = (struct in_addr_data
) {
1190 int config_parse_dnssec_negative_trust_anchors(
1192 const char *filename
,
1194 const char *section
,
1195 unsigned section_line
,
1202 const char *p
= rvalue
;
1210 if (isempty(rvalue
)) {
1211 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1216 _cleanup_free_
char *w
= NULL
;
1218 r
= extract_first_word(&p
, &w
, NULL
, 0);
1220 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1221 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1227 r
= dns_name_is_valid(w
);
1229 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1230 "%s is not a valid domain name, ignoring.", w
);
1234 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1238 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1248 int config_parse_ntp(
1250 const char *filename
,
1252 const char *section
,
1253 unsigned section_line
,
1267 if (isempty(rvalue
)) {
1273 _cleanup_free_
char *w
= NULL
;
1275 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1279 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1280 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1286 r
= dns_name_is_valid_or_address(w
);
1288 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1289 "%s is not a valid domain name or IP address, ignoring.", w
);
1293 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1294 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1295 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1296 MAX_NTP_SERVERS
, w
);
1300 r
= strv_consume(l
, TAKE_PTR(w
));
1308 int config_parse_required_for_online(
1310 const char *filename
,
1312 const char *section
,
1313 unsigned section_line
,
1320 Network
*network
= data
;
1321 LinkOperationalStateRange range
;
1322 bool required
= true;
1325 if (isempty(rvalue
)) {
1326 network
->required_for_online
= true;
1327 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1331 r
= parse_operational_state_range(rvalue
, &range
);
1333 r
= parse_boolean(rvalue
);
1335 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1336 "Failed to parse %s= setting, ignoring assignment: %s",
1342 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1345 network
->required_for_online
= required
;
1346 network
->required_operstate_for_online
= range
;
1351 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1352 "Failed to parse KeepConfiguration= setting");
1354 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1355 [KEEP_CONFIGURATION_NO
] = "no",
1356 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1357 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1358 [KEEP_CONFIGURATION_STATIC
] = "static",
1359 [KEEP_CONFIGURATION_YES
] = "yes",
1362 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);