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 .dhcp_use_gateway
= true,
388 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
389 .dhcp_send_hostname
= true,
390 .dhcp_send_release
= true,
391 /* To enable/disable RFC7844 Anonymity Profiles */
392 .dhcp_anonymize
= false,
393 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
394 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
395 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
396 .dhcp_route_table
= RT_TABLE_MAIN
,
397 .dhcp_route_table_set
= false,
398 /* NOTE: from man: UseMTU=... Defaults to false*/
399 .dhcp_use_mtu
= false,
400 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
401 .dhcp_use_timezone
= false,
402 .rapid_commit
= true,
404 .dhcp6_use_ntp
= true,
405 .dhcp6_use_dns
= true,
407 .dhcp_server_emit_dns
= true,
408 .dhcp_server_emit_ntp
= true,
409 .dhcp_server_emit_sip
= true,
410 .dhcp_server_emit_router
= true,
411 .dhcp_server_emit_timezone
= true,
413 .router_emit_dns
= true,
414 .router_emit_domains
= true,
419 .allow_port_to_be_root
= -1,
421 .multicast_flood
= -1,
422 .multicast_to_unicast
= -1,
423 .neighbor_suppression
= -1,
425 .bridge_proxy_arp
= -1,
426 .bridge_proxy_arp_wifi
= -1,
427 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
428 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
430 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
432 .dns_default_route
= -1,
433 .llmnr
= RESOLVE_SUPPORT_YES
,
434 .mdns
= RESOLVE_SUPPORT_NO
,
435 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
436 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
438 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
439 .link_local
= _ADDRESS_FAMILY_INVALID
,
441 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
442 .ipv6_accept_ra
= -1,
443 .ipv6_dad_transmits
= -1,
444 .ipv6_hop_limit
= -1,
445 .ipv6_proxy_ndp
= -1,
446 .duid
.type
= _DUID_TYPE_INVALID
,
451 .ipv6_accept_ra_use_dns
= true,
452 .ipv6_accept_ra_use_autonomous_prefix
= true,
453 .ipv6_accept_ra_use_onlink_prefix
= true,
454 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
455 .ipv6_accept_ra_route_table_set
= false,
456 .ipv6_accept_ra_start_dhcp6_client
= true,
458 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
460 .can_triple_sampling
= -1,
461 .can_termination
= -1,
462 .ip_service_type
= -1,
465 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
472 "RoutingPolicyRule\0"
475 "DHCP\0" /* compat */
480 "IPv6NDPProxyAddress\0"
484 "IPv6PrefixDelegation\0"
487 "TrafficControlQueueingDiscipline\0"
493 "DeficitRoundRobinScheduler\0"
494 "DeficitRoundRobinSchedulerClass\0"
499 "FairQueueingControlledDelay\0"
500 "GenericRandomEarlyDetection\0"
501 "HeavyHitterFilter\0"
502 "HierarchyTokenBucket\0"
503 "HierarchyTokenBucketClass\0"
506 "StochasticFairBlue\0"
507 "StochasticFairnessQueueing\0"
508 "TokenBucketFilter\0"
509 "TrivialLinkEqualizer\0",
510 config_item_perf_lookup
, network_network_gperf_lookup
,
511 CONFIG_PARSE_WARN
, network
);
515 network_apply_anonymize_if_set(network
);
517 r
= network_add_ipv4ll_route(network
);
519 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
521 r
= network_add_default_route_on_device(network
);
523 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
527 if (stat(filename
, &stats
) < 0)
529 network
->timestamp
= timespec_load(&stats
.st_mtim
);
531 if (network_verify(network
) < 0)
532 /* Ignore .network files that do not match the conditions. */
535 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
539 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
547 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
548 _cleanup_strv_free_
char **files
= NULL
;
554 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
556 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
558 return log_error_errno(r
, "Failed to enumerate network files: %m");
560 STRV_FOREACH(f
, files
) {
561 r
= network_load_one(manager
, networks
, *f
);
563 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
569 int network_reload(Manager
*manager
) {
570 OrderedHashmap
*new_networks
= NULL
;
577 r
= network_load(manager
, &new_networks
);
581 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
582 r
= network_get_by_name(manager
, n
->name
, &old
);
584 continue; /* The .network file is new. */
586 if (n
->timestamp
!= old
->timestamp
)
587 continue; /* The .network file is modified. */
589 if (!streq(n
->filename
, old
->filename
))
592 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
600 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
601 manager
->networks
= new_networks
;
606 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
611 static Network
*network_free(Network
*network
) {
612 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
613 RoutePrefix
*route_prefix
;
614 RoutingPolicyRule
*rule
;
626 free(network
->filename
);
628 set_free_free(network
->match_mac
);
629 set_free_free(network
->match_permanent_mac
);
630 strv_free(network
->match_path
);
631 strv_free(network
->match_driver
);
632 strv_free(network
->match_type
);
633 strv_free(network
->match_name
);
634 strv_free(network
->match_property
);
635 strv_free(network
->match_wlan_iftype
);
636 strv_free(network
->match_ssid
);
637 set_free_free(network
->match_bssid
);
638 condition_free_list(network
->conditions
);
640 free(network
->description
);
641 free(network
->dhcp_vendor_class_identifier
);
642 strv_free(network
->dhcp_user_class
);
643 free(network
->dhcp_hostname
);
644 set_free(network
->dhcp_black_listed_ip
);
645 set_free(network
->dhcp_request_options
);
648 if (network
->dhcp_acd
)
649 sd_ipv4acd_unref(network
->dhcp_acd
);
651 strv_free(network
->ntp
);
653 strv_free(network
->sip
);
654 ordered_set_free_free(network
->search_domains
);
655 ordered_set_free_free(network
->route_domains
);
656 strv_free(network
->bind_carrier
);
658 ordered_set_free_free(network
->router_search_domains
);
659 free(network
->router_dns
);
660 set_free_free(network
->ndisc_black_listed_prefix
);
662 free(network
->bridge_name
);
663 free(network
->bond_name
);
664 free(network
->vrf_name
);
665 hashmap_free_free_key(network
->stacked_netdev_names
);
666 netdev_unref(network
->bridge
);
667 netdev_unref(network
->bond
);
668 netdev_unref(network
->vrf
);
669 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
671 while ((route
= network
->static_routes
))
674 while ((nexthop
= network
->static_nexthops
))
675 nexthop_free(nexthop
);
677 while ((address
= network
->static_addresses
))
678 address_free(address
);
680 while ((fdb_entry
= network
->static_fdb_entries
))
681 fdb_entry_free(fdb_entry
);
683 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
684 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
686 while ((neighbor
= network
->neighbors
))
687 neighbor_free(neighbor
);
689 while ((label
= network
->address_labels
))
690 address_label_free(label
);
692 while ((prefix
= network
->static_prefixes
))
695 while ((route_prefix
= network
->static_route_prefixes
))
696 route_prefix_free(route_prefix
);
698 while ((rule
= network
->rules
))
699 routing_policy_rule_free(rule
);
701 hashmap_free(network
->addresses_by_section
);
702 hashmap_free(network
->routes_by_section
);
703 hashmap_free(network
->nexthops_by_section
);
704 hashmap_free(network
->fdb_entries_by_section
);
705 hashmap_free(network
->neighbors_by_section
);
706 hashmap_free(network
->address_labels_by_section
);
707 hashmap_free(network
->prefixes_by_section
);
708 hashmap_free(network
->route_prefixes_by_section
);
709 hashmap_free(network
->rules_by_section
);
710 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
712 if (network
->manager
&&
713 network
->manager
->duids_requesting_uuid
)
714 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
718 free(network
->dhcp_server_timezone
);
719 free(network
->dhcp_server_dns
);
720 free(network
->dhcp_server_ntp
);
721 free(network
->dhcp_server_sip
);
723 set_free_free(network
->dnssec_negative_trust_anchors
);
725 ordered_hashmap_free(network
->dhcp_client_send_options
);
726 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
727 ordered_hashmap_free(network
->dhcp_server_send_options
);
728 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
729 ordered_hashmap_free(network
->ipv6_tokens
);
731 return mfree(network
);
734 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
736 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
743 network
= ordered_hashmap_get(manager
->networks
, name
);
752 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
753 const char *ifname
, char * const *alternative_names
,
754 const struct ether_addr
*address
, const struct ether_addr
*permanent_address
,
755 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
763 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
764 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
765 network
->match_path
, network
->match_driver
,
766 network
->match_type
, network
->match_name
, network
->match_property
,
767 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
768 iftype
, device
, address
, permanent_address
,
769 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
770 if (network
->match_name
&& device
) {
772 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
774 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
775 (void) safe_atou8(attr
, &name_assign_type
);
777 if (name_assign_type
== NET_NAME_ENUM
)
778 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
779 ifname
, network
->filename
);
781 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
783 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
794 int network_apply(Network
*network
, Link
*link
) {
798 link
->network
= network_ref(network
);
800 if (network
->n_dns
> 0 ||
801 !strv_isempty(network
->ntp
) ||
802 !ordered_set_isempty(network
->search_domains
) ||
803 !ordered_set_isempty(network
->route_domains
))
809 bool network_has_static_ipv6_configurations(Network
*network
) {
817 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
818 if (address
->family
== AF_INET6
)
821 LIST_FOREACH(routes
, route
, network
->static_routes
)
822 if (route
->family
== AF_INET6
)
825 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
826 if (fdb
->family
== AF_INET6
)
829 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
830 if (neighbor
->family
== AF_INET6
)
833 if (!LIST_IS_EMPTY(network
->address_labels
))
836 if (!LIST_IS_EMPTY(network
->static_prefixes
))
842 int config_parse_stacked_netdev(const char *unit
,
843 const char *filename
,
846 unsigned section_line
,
852 _cleanup_free_
char *name
= NULL
;
853 NetDevKind kind
= ltype
;
862 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
863 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
864 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
867 if (!ifname_valid(rvalue
)) {
868 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
869 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
873 name
= strdup(rvalue
);
877 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
881 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
883 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
884 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
886 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
887 "NetDev '%s' specified twice, ignoring.", name
);
894 int config_parse_domains(
896 const char *filename
,
899 unsigned section_line
,
914 if (isempty(rvalue
)) {
915 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
916 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
922 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
926 r
= extract_first_word(&p
, &w
, NULL
, 0);
928 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
929 "Failed to extract search or route domain, ignoring: %s", rvalue
);
935 is_route
= w
[0] == '~';
936 domain
= is_route
? w
+ 1 : w
;
938 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
939 /* If the root domain appears as is, or the special token "*" is found, we'll
940 * consider this as routing domain, unconditionally. */
942 domain
= "."; /* make sure we don't allow empty strings, thus write the root
945 r
= dns_name_normalize(domain
, 0, &normalized
);
947 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
948 "'%s' is not a valid domain name, ignoring.", domain
);
954 if (is_localhost(domain
)) {
955 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
956 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
962 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
963 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
967 r
= ordered_set_put_strdup(*set
, domain
);
975 int config_parse_ipv6token(
977 const char *filename
,
980 unsigned section_line
,
987 union in_addr_union buffer
;
988 struct in6_addr
*token
= data
;
996 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
998 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
999 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1003 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1004 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1005 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1009 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1010 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1011 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1015 *token
= buffer
.in6
;
1020 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1021 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1022 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1023 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1026 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1027 IPV6_PRIVACY_EXTENSIONS_YES
);
1029 int config_parse_ipv6_privacy_extensions(
1031 const char *filename
,
1033 const char *section
,
1034 unsigned section_line
,
1041 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1046 assert(ipv6_privacy_extensions
);
1048 s
= ipv6_privacy_extensions_from_string(rvalue
);
1050 if (streq(rvalue
, "kernel"))
1051 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1053 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1054 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1059 *ipv6_privacy_extensions
= s
;
1064 int config_parse_hostname(
1066 const char *filename
,
1068 const char *section
,
1069 unsigned section_line
,
1076 _cleanup_free_
char *hn
= NULL
;
1077 char **hostname
= data
;
1084 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1088 if (!hostname_is_valid(hn
, false)) {
1089 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1090 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1094 r
= dns_name_is_valid(hn
);
1096 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1097 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1101 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1102 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1106 return free_and_replace(*hostname
, hn
);
1109 int config_parse_timezone(
1111 const char *filename
,
1113 const char *section
,
1114 unsigned section_line
,
1121 _cleanup_free_
char *tz
= NULL
;
1122 char **datap
= data
;
1129 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1133 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1134 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1135 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1139 return free_and_replace(*datap
, tz
);
1142 int config_parse_dns(
1144 const char *filename
,
1146 const char *section
,
1147 unsigned section_line
,
1154 Network
*n
= userdata
;
1162 _cleanup_free_
char *w
= NULL
;
1163 union in_addr_union a
;
1164 struct in_addr_data
*m
;
1167 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1171 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1172 "Invalid syntax, ignoring: %s", rvalue
);
1178 r
= in_addr_from_string_auto(w
, &family
, &a
);
1180 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1181 "Failed to parse dns server address, ignoring: %s", w
);
1185 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1189 m
[n
->n_dns
++] = (struct in_addr_data
) {
1200 int config_parse_dnssec_negative_trust_anchors(
1202 const char *filename
,
1204 const char *section
,
1205 unsigned section_line
,
1212 const char *p
= rvalue
;
1220 if (isempty(rvalue
)) {
1221 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1226 _cleanup_free_
char *w
= NULL
;
1228 r
= extract_first_word(&p
, &w
, NULL
, 0);
1230 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1231 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1237 r
= dns_name_is_valid(w
);
1239 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1240 "%s is not a valid domain name, ignoring.", w
);
1244 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1248 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1258 int config_parse_ntp(
1260 const char *filename
,
1262 const char *section
,
1263 unsigned section_line
,
1277 if (isempty(rvalue
)) {
1283 _cleanup_free_
char *w
= NULL
;
1285 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1289 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1290 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1296 r
= dns_name_is_valid_or_address(w
);
1298 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1299 "%s is not a valid domain name or IP address, ignoring.", w
);
1303 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1304 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1305 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1306 MAX_NTP_SERVERS
, w
);
1310 r
= strv_consume(l
, TAKE_PTR(w
));
1318 int config_parse_required_for_online(
1320 const char *filename
,
1322 const char *section
,
1323 unsigned section_line
,
1330 Network
*network
= data
;
1331 LinkOperationalStateRange range
;
1332 bool required
= true;
1335 if (isempty(rvalue
)) {
1336 network
->required_for_online
= true;
1337 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1341 r
= parse_operational_state_range(rvalue
, &range
);
1343 r
= parse_boolean(rvalue
);
1345 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1346 "Failed to parse %s= setting, ignoring assignment: %s",
1352 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1355 network
->required_for_online
= required
;
1356 network
->required_operstate_for_online
= range
;
1361 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1362 "Failed to parse KeepConfiguration= setting");
1364 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1365 [KEEP_CONFIGURATION_NO
] = "no",
1366 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1367 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1368 [KEEP_CONFIGURATION_STATIC
] = "static",
1369 [KEEP_CONFIGURATION_YES
] = "yes",
1372 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);