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"
19 #include "path-lookup.h"
21 #include "socket-util.h"
22 #include "stat-util.h"
23 #include "string-table.h"
24 #include "string-util.h"
29 /* Let's assume that anything above this number is a user misconfiguration. */
30 #define MAX_NTP_SERVERS 128
32 /* Set defaults following RFC7844 */
33 void network_apply_anonymize_if_set(Network
*network
) {
34 if (!network
->dhcp_anonymize
)
37 SHOULD NOT send the Host Name option */
38 network
->dhcp_send_hostname
= false;
39 /* RFC7844 section 3.:
40 MAY contain the Client Identifier option
42 clients MUST use client identifiers based solely
43 on the link-layer address */
44 /* NOTE: Using MAC, as it does not reveal extra information,
45 * and some servers might not answer if this option is not sent */
46 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
48 SHOULD NOT use the Vendor Class Identifier option */
49 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
50 /* RFC7844 section 3.6.:
51 The client intending to protect its privacy SHOULD only request a
52 minimal number of options in the PRL and SHOULD also randomly shuffle
53 the ordering of option codes in the PRL. If this random ordering
54 cannot be implemented, the client MAY order the option codes in the
55 PRL by option code number (lowest to highest).
57 /* NOTE: dhcp_use_mtu is false by default,
58 * though it was not initiallized to any value in network_load_one.
59 * Maybe there should be another var called *send*?
60 * (to use the MTU sent by the server but to do not send
61 * the option in the PRL). */
62 network
->dhcp_use_mtu
= false;
63 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
64 * but this is needed to use them. */
65 network
->dhcp_use_routes
= true;
66 /* RFC7844 section 3.6.
67 * same comments as previous option */
68 network
->dhcp_use_timezone
= false;
71 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
72 const char *kind_string
;
76 /* For test-networkd-conf, the check must be earlier than the assertions. */
81 assert(network
->manager
);
82 assert(network
->filename
);
85 if (kind
== _NETDEV_KIND_TUNNEL
)
86 kind_string
= "tunnel";
88 kind_string
= netdev_kind_to_string(kind
);
90 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
91 "%s: Invalid NetDev kind of %s, ignoring assignment.",
92 network
->filename
, name
);
95 r
= netdev_get(network
->manager
, name
, &netdev
);
97 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
98 network
->filename
, name
);
100 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
107 NETDEV_KIND_IP6GRETAP
,
111 NETDEV_KIND_ERSPAN
)))
112 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
113 "%s: NetDev %s is not a %s, ignoring assignment",
114 network
->filename
, name
, kind_string
);
116 *ret_netdev
= netdev_ref(netdev
);
120 static int network_resolve_stacked_netdevs(Network
*network
) {
127 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
128 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
130 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
134 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
138 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
140 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
141 network
->filename
, (const char *) name
);
149 int network_verify(Network
*network
) {
150 RoutePrefix
*route_prefix
, *route_prefix_next
;
151 RoutingPolicyRule
*rule
, *rule_next
;
152 Neighbor
*neighbor
, *neighbor_next
;
153 AddressLabel
*label
, *label_next
;
154 NextHop
*nexthop
, *nextnop_next
;
155 Address
*address
, *address_next
;
156 Prefix
*prefix
, *prefix_next
;
157 Route
*route
, *route_next
;
158 FdbEntry
*fdb
, *fdb_next
;
163 assert(network
->filename
);
165 if (set_isempty(network
->match_mac
) && set_isempty(network
->match_permanent_mac
) &&
166 strv_isempty(network
->match_path
) && strv_isempty(network
->match_driver
) &&
167 strv_isempty(network
->match_type
) && strv_isempty(network
->match_name
) &&
168 strv_isempty(network
->match_property
) && strv_isempty(network
->match_ssid
) && !network
->conditions
)
169 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
170 "%s: No valid settings found in the [Match] section, ignoring file. "
171 "To match all interfaces, add Name=* in the [Match] section.",
174 /* skip out early if configuration does not match the environment */
175 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
176 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
177 "%s: Conditions in the file do not match the system environment, skipping.",
180 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
181 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
182 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
183 (void) network_resolve_stacked_netdevs(network
);
185 /* Free unnecessary entries. */
186 network
->bond_name
= mfree(network
->bond_name
);
187 network
->bridge_name
= mfree(network
->bridge_name
);
188 network
->vrf_name
= mfree(network
->vrf_name
);
189 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
192 /* Bonding slave does not support addressing. */
193 if (network
->ipv6_accept_ra
> 0) {
194 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
196 network
->ipv6_accept_ra
= 0;
198 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
199 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
201 network
->link_local
= ADDRESS_FAMILY_NO
;
203 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
204 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
206 network
->dhcp
= ADDRESS_FAMILY_NO
;
208 if (network
->dhcp_server
) {
209 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
211 network
->dhcp_server
= false;
213 if (network
->n_static_addresses
> 0) {
214 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
216 while ((address
= network
->static_addresses
))
217 address_free(address
);
219 if (network
->n_static_routes
> 0) {
220 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
222 while ((route
= network
->static_routes
))
227 if (network
->link_local
< 0)
228 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
230 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
231 if (network
->ipv6_accept_ra
> 0) {
232 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
233 "Disabling IPv6AcceptRA=.", network
->filename
);
234 network
->ipv6_accept_ra
= false;
237 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
238 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
239 "Disabling DHCPv6 client.", network
->filename
);
240 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
243 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
244 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
245 "Disabling IPv6PrefixDelegation=.", network
->filename
);
246 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
250 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
251 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
252 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
253 "Disabling the fallback assignment.", network
->filename
);
254 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
257 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
258 network
->ipv6_accept_ra
= false;
260 /* IPMasquerade=yes implies IPForward=yes */
261 if (network
->ip_masquerade
)
262 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
264 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
265 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
266 "Disabling UseMTU=.", network
->filename
);
267 network
->dhcp_use_mtu
= false;
270 if (network
->dhcp_critical
>= 0) {
271 if (network
->keep_configuration
>= 0)
272 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
273 "Ignoring CriticalConnection=.", network
->filename
);
274 else if (network
->dhcp_critical
)
275 /* CriticalConnection=yes also preserve foreign static configurations. */
276 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
278 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
281 if (network
->keep_configuration
< 0)
282 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
284 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
285 if (address_section_verify(address
) < 0)
286 address_free(address
);
288 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
289 if (route_section_verify(route
, network
) < 0)
292 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
293 if (nexthop_section_verify(nexthop
) < 0)
294 nexthop_free(nexthop
);
296 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
297 if (section_is_invalid(fdb
->section
))
300 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
301 if (neighbor_section_verify(neighbor
) < 0)
302 neighbor_free(neighbor
);
304 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
305 if (section_is_invalid(label
->section
))
306 address_label_free(label
);
308 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
309 if (section_is_invalid(prefix
->section
))
312 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
313 if (section_is_invalid(route_prefix
->section
))
314 route_prefix_free(route_prefix
);
316 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
317 if (routing_policy_rule_section_verify(rule
) < 0)
318 routing_policy_rule_free(rule
);
320 bool has_root
= false, has_clsact
= false;
321 ORDERED_HASHMAP_FOREACH(tc
, network
->tc_by_section
, i
)
322 if (traffic_control_section_verify(tc
, &has_root
, &has_clsact
) < 0)
323 traffic_control_free(tc
);
328 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
329 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
330 _cleanup_(network_unrefp
) Network
*network
= NULL
;
331 _cleanup_fclose_
FILE *file
= NULL
;
332 const char *dropin_dirname
;
339 file
= fopen(filename
, "re");
347 if (null_or_empty_fd(fileno(file
))) {
348 log_debug("Skipping empty file: %s", filename
);
352 fname
= strdup(filename
);
356 name
= strdup(basename(filename
));
360 d
= strrchr(name
, '.');
366 dropin_dirname
= strjoina(name
, ".network.d");
368 network
= new(Network
, 1);
372 *network
= (Network
) {
373 .filename
= TAKE_PTR(fname
),
374 .name
= TAKE_PTR(name
),
379 .required_for_online
= true,
380 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
381 .dhcp
= ADDRESS_FAMILY_NO
,
383 .dhcp_use_ntp
= true,
384 .dhcp_use_sip
= true,
385 .dhcp_use_dns
= true,
386 .dhcp_use_hostname
= true,
387 .dhcp_use_routes
= true,
388 .dhcp_use_gateway
= true,
389 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
390 .dhcp_send_hostname
= true,
391 .dhcp_send_release
= true,
392 /* To enable/disable RFC7844 Anonymity Profiles */
393 .dhcp_anonymize
= false,
394 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
395 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
396 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
397 .dhcp_route_table
= RT_TABLE_MAIN
,
398 .dhcp_route_table_set
= false,
399 /* NOTE: from man: UseMTU=... Defaults to false*/
400 .dhcp_use_mtu
= false,
401 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
402 .dhcp_use_timezone
= false,
403 .rapid_commit
= true,
405 .dhcp6_use_ntp
= true,
406 .dhcp6_use_dns
= true,
408 .dhcp_server_emit_dns
= true,
409 .dhcp_server_emit_ntp
= true,
410 .dhcp_server_emit_sip
= true,
411 .dhcp_server_emit_router
= true,
412 .dhcp_server_emit_timezone
= true,
414 .router_emit_dns
= true,
415 .router_emit_domains
= true,
420 .allow_port_to_be_root
= -1,
422 .multicast_flood
= -1,
423 .multicast_to_unicast
= -1,
424 .neighbor_suppression
= -1,
426 .bridge_proxy_arp
= -1,
427 .bridge_proxy_arp_wifi
= -1,
428 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
429 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
431 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
433 .dns_default_route
= -1,
434 .llmnr
= RESOLVE_SUPPORT_YES
,
435 .mdns
= RESOLVE_SUPPORT_NO
,
436 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
437 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
439 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
440 .link_local
= _ADDRESS_FAMILY_INVALID
,
442 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
443 .ipv6_accept_ra
= -1,
444 .ipv6_dad_transmits
= -1,
445 .ipv6_hop_limit
= -1,
446 .ipv6_proxy_ndp
= -1,
447 .duid
.type
= _DUID_TYPE_INVALID
,
452 .ipv6_accept_ra_use_dns
= true,
453 .ipv6_accept_ra_use_autonomous_prefix
= true,
454 .ipv6_accept_ra_use_onlink_prefix
= true,
455 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
456 .ipv6_accept_ra_route_table_set
= false,
457 .ipv6_accept_ra_start_dhcp6_client
= true,
459 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
461 .can_triple_sampling
= -1,
462 .can_termination
= -1,
463 .ip_service_type
= -1,
466 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
473 "RoutingPolicyRule\0"
476 "DHCP\0" /* compat */
481 "IPv6NDPProxyAddress\0"
485 "IPv6PrefixDelegation\0"
489 "TrafficControlQueueingDiscipline\0"
495 "DeficitRoundRobinScheduler\0"
496 "DeficitRoundRobinSchedulerClass\0"
501 "FairQueueingControlledDelay\0"
502 "GenericRandomEarlyDetection\0"
503 "HeavyHitterFilter\0"
504 "HierarchyTokenBucket\0"
505 "HierarchyTokenBucketClass\0"
508 "StochasticFairBlue\0"
509 "StochasticFairnessQueueing\0"
510 "TokenBucketFilter\0"
511 "TrivialLinkEqualizer\0",
512 config_item_perf_lookup
, network_network_gperf_lookup
,
513 CONFIG_PARSE_WARN
, network
);
517 network_apply_anonymize_if_set(network
);
519 r
= network_add_ipv4ll_route(network
);
521 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
523 r
= network_add_default_route_on_device(network
);
525 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
529 if (stat(filename
, &stats
) < 0)
531 network
->timestamp
= timespec_load(&stats
.st_mtim
);
533 if (network_verify(network
) < 0)
534 /* Ignore .network files that do not match the conditions. */
537 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
541 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
549 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
550 _cleanup_strv_free_
char **files
= NULL
;
556 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
558 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
560 return log_error_errno(r
, "Failed to enumerate network files: %m");
562 STRV_FOREACH(f
, files
) {
563 r
= network_load_one(manager
, networks
, *f
);
565 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
571 int network_reload(Manager
*manager
) {
572 OrderedHashmap
*new_networks
= NULL
;
579 r
= network_load(manager
, &new_networks
);
583 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
584 r
= network_get_by_name(manager
, n
->name
, &old
);
586 continue; /* The .network file is new. */
588 if (n
->timestamp
!= old
->timestamp
)
589 continue; /* The .network file is modified. */
591 if (!streq(n
->filename
, old
->filename
))
594 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
602 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
603 manager
->networks
= new_networks
;
608 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
613 static Network
*network_free(Network
*network
) {
614 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
615 RoutePrefix
*route_prefix
;
616 RoutingPolicyRule
*rule
;
628 free(network
->filename
);
630 set_free_free(network
->match_mac
);
631 set_free_free(network
->match_permanent_mac
);
632 strv_free(network
->match_path
);
633 strv_free(network
->match_driver
);
634 strv_free(network
->match_type
);
635 strv_free(network
->match_name
);
636 strv_free(network
->match_property
);
637 strv_free(network
->match_wlan_iftype
);
638 strv_free(network
->match_ssid
);
639 set_free_free(network
->match_bssid
);
640 condition_free_list(network
->conditions
);
642 free(network
->description
);
643 free(network
->dhcp_vendor_class_identifier
);
644 free(network
->dhcp_mudurl
);
645 strv_free(network
->dhcp_user_class
);
646 free(network
->dhcp_hostname
);
647 set_free(network
->dhcp_black_listed_ip
);
648 set_free(network
->dhcp_request_options
);
650 free(network
->dhcp6_mudurl
);
652 if (network
->dhcp_acd
)
653 sd_ipv4acd_unref(network
->dhcp_acd
);
655 strv_free(network
->ntp
);
657 strv_free(network
->sip
);
658 strv_free(network
->smtp
);
659 ordered_set_free_free(network
->search_domains
);
660 ordered_set_free_free(network
->route_domains
);
661 strv_free(network
->bind_carrier
);
663 ordered_set_free_free(network
->router_search_domains
);
664 free(network
->router_dns
);
665 set_free_free(network
->ndisc_black_listed_prefix
);
667 free(network
->bridge_name
);
668 free(network
->bond_name
);
669 free(network
->vrf_name
);
670 hashmap_free_free_key(network
->stacked_netdev_names
);
671 netdev_unref(network
->bridge
);
672 netdev_unref(network
->bond
);
673 netdev_unref(network
->vrf
);
674 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
676 while ((route
= network
->static_routes
))
679 while ((nexthop
= network
->static_nexthops
))
680 nexthop_free(nexthop
);
682 while ((address
= network
->static_addresses
))
683 address_free(address
);
685 while ((fdb_entry
= network
->static_fdb_entries
))
686 fdb_entry_free(fdb_entry
);
688 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
689 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
691 while ((neighbor
= network
->neighbors
))
692 neighbor_free(neighbor
);
694 while ((label
= network
->address_labels
))
695 address_label_free(label
);
697 while ((prefix
= network
->static_prefixes
))
700 while ((route_prefix
= network
->static_route_prefixes
))
701 route_prefix_free(route_prefix
);
703 while ((rule
= network
->rules
))
704 routing_policy_rule_free(rule
);
706 hashmap_free(network
->addresses_by_section
);
707 hashmap_free(network
->routes_by_section
);
708 hashmap_free(network
->nexthops_by_section
);
709 hashmap_free(network
->fdb_entries_by_section
);
710 hashmap_free(network
->neighbors_by_section
);
711 hashmap_free(network
->address_labels_by_section
);
712 hashmap_free(network
->prefixes_by_section
);
713 hashmap_free(network
->route_prefixes_by_section
);
714 hashmap_free(network
->rules_by_section
);
715 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
717 if (network
->manager
&&
718 network
->manager
->duids_requesting_uuid
)
719 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
723 free(network
->dhcp_server_timezone
);
724 free(network
->dhcp_server_dns
);
725 free(network
->dhcp_server_ntp
);
726 free(network
->dhcp_server_sip
);
728 set_free_free(network
->dnssec_negative_trust_anchors
);
730 free(network
->lldp_mud
);
732 ordered_hashmap_free(network
->dhcp_client_send_options
);
733 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
734 ordered_hashmap_free(network
->dhcp_server_send_options
);
735 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
736 ordered_hashmap_free(network
->ipv6_tokens
);
738 return mfree(network
);
741 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
743 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
750 network
= ordered_hashmap_get(manager
->networks
, name
);
759 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
760 const char *ifname
, char * const *alternative_names
,
761 const struct ether_addr
*address
, const struct ether_addr
*permanent_address
,
762 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
770 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
771 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
772 network
->match_path
, network
->match_driver
,
773 network
->match_type
, network
->match_name
, network
->match_property
,
774 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
775 iftype
, device
, address
, permanent_address
,
776 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
777 if (network
->match_name
&& device
) {
779 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
781 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
782 (void) safe_atou8(attr
, &name_assign_type
);
784 if (name_assign_type
== NET_NAME_ENUM
)
785 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
786 ifname
, network
->filename
);
788 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
790 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
801 int network_apply(Network
*network
, Link
*link
) {
805 link
->network
= network_ref(network
);
807 if (network
->n_dns
> 0 ||
808 !strv_isempty(network
->ntp
) ||
809 !ordered_set_isempty(network
->search_domains
) ||
810 !ordered_set_isempty(network
->route_domains
))
816 bool network_has_static_ipv6_configurations(Network
*network
) {
824 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
825 if (address
->family
== AF_INET6
)
828 LIST_FOREACH(routes
, route
, network
->static_routes
)
829 if (route
->family
== AF_INET6
)
832 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
833 if (fdb
->family
== AF_INET6
)
836 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
837 if (neighbor
->family
== AF_INET6
)
840 if (!LIST_IS_EMPTY(network
->address_labels
))
843 if (!LIST_IS_EMPTY(network
->static_prefixes
))
849 int config_parse_stacked_netdev(const char *unit
,
850 const char *filename
,
853 unsigned section_line
,
859 _cleanup_free_
char *name
= NULL
;
860 NetDevKind kind
= ltype
;
869 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
870 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
871 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
874 if (!ifname_valid(rvalue
)) {
875 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
876 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
880 name
= strdup(rvalue
);
884 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
888 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
890 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
891 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
893 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
894 "NetDev '%s' specified twice, ignoring.", name
);
901 int config_parse_domains(
903 const char *filename
,
906 unsigned section_line
,
921 if (isempty(rvalue
)) {
922 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
923 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
929 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
933 r
= extract_first_word(&p
, &w
, NULL
, 0);
935 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
936 "Failed to extract search or route domain, ignoring: %s", rvalue
);
942 is_route
= w
[0] == '~';
943 domain
= is_route
? w
+ 1 : w
;
945 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
946 /* If the root domain appears as is, or the special token "*" is found, we'll
947 * consider this as routing domain, unconditionally. */
949 domain
= "."; /* make sure we don't allow empty strings, thus write the root
952 r
= dns_name_normalize(domain
, 0, &normalized
);
954 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
955 "'%s' is not a valid domain name, ignoring.", domain
);
961 if (is_localhost(domain
)) {
962 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
963 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
969 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
970 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
974 r
= ordered_set_put_strdup(*set
, domain
);
982 int config_parse_ipv6token(
984 const char *filename
,
987 unsigned section_line
,
994 union in_addr_union buffer
;
995 struct in6_addr
*token
= data
;
1003 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
1005 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1006 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1010 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1011 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1012 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1016 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1017 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1018 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1022 *token
= buffer
.in6
;
1027 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1028 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1029 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1030 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1033 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1034 IPV6_PRIVACY_EXTENSIONS_YES
);
1036 int config_parse_ipv6_privacy_extensions(
1038 const char *filename
,
1040 const char *section
,
1041 unsigned section_line
,
1048 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1053 assert(ipv6_privacy_extensions
);
1055 s
= ipv6_privacy_extensions_from_string(rvalue
);
1057 if (streq(rvalue
, "kernel"))
1058 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1060 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1061 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1066 *ipv6_privacy_extensions
= s
;
1071 int config_parse_hostname(
1073 const char *filename
,
1075 const char *section
,
1076 unsigned section_line
,
1083 _cleanup_free_
char *hn
= NULL
;
1084 char **hostname
= data
;
1091 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1095 if (!hostname_is_valid(hn
, false)) {
1096 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1097 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1101 r
= dns_name_is_valid(hn
);
1103 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1104 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1108 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1109 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1113 return free_and_replace(*hostname
, hn
);
1116 int config_parse_timezone(
1118 const char *filename
,
1120 const char *section
,
1121 unsigned section_line
,
1128 _cleanup_free_
char *tz
= NULL
;
1129 char **datap
= data
;
1136 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1140 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1141 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1142 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1146 return free_and_replace(*datap
, tz
);
1149 int config_parse_dns(
1151 const char *filename
,
1153 const char *section
,
1154 unsigned section_line
,
1161 Network
*n
= userdata
;
1169 _cleanup_free_
char *w
= NULL
;
1170 union in_addr_union a
;
1171 struct in_addr_data
*m
;
1174 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1178 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1179 "Invalid syntax, ignoring: %s", rvalue
);
1185 r
= in_addr_from_string_auto(w
, &family
, &a
);
1187 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1188 "Failed to parse dns server address, ignoring: %s", w
);
1192 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1196 m
[n
->n_dns
++] = (struct in_addr_data
) {
1207 int config_parse_dnssec_negative_trust_anchors(
1209 const char *filename
,
1211 const char *section
,
1212 unsigned section_line
,
1219 const char *p
= rvalue
;
1227 if (isempty(rvalue
)) {
1228 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1233 _cleanup_free_
char *w
= NULL
;
1235 r
= extract_first_word(&p
, &w
, NULL
, 0);
1237 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1238 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1244 r
= dns_name_is_valid(w
);
1246 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1247 "%s is not a valid domain name, ignoring.", w
);
1251 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1255 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1265 int config_parse_ntp(
1267 const char *filename
,
1269 const char *section
,
1270 unsigned section_line
,
1284 if (isempty(rvalue
)) {
1290 _cleanup_free_
char *w
= NULL
;
1292 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1296 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1297 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1303 r
= dns_name_is_valid_or_address(w
);
1305 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1306 "%s is not a valid domain name or IP address, ignoring.", w
);
1310 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1311 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1312 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1313 MAX_NTP_SERVERS
, w
);
1317 r
= strv_consume(l
, TAKE_PTR(w
));
1325 int config_parse_required_for_online(
1327 const char *filename
,
1329 const char *section
,
1330 unsigned section_line
,
1337 Network
*network
= data
;
1338 LinkOperationalStateRange range
;
1339 bool required
= true;
1342 if (isempty(rvalue
)) {
1343 network
->required_for_online
= true;
1344 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1348 r
= parse_operational_state_range(rvalue
, &range
);
1350 r
= parse_boolean(rvalue
);
1352 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1353 "Failed to parse %s= setting, ignoring assignment: %s",
1359 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1362 network
->required_for_online
= required
;
1363 network
->required_operstate_for_online
= range
;
1368 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1369 "Failed to parse KeepConfiguration= setting");
1371 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1372 [KEEP_CONFIGURATION_NO
] = "no",
1373 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1374 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1375 [KEEP_CONFIGURATION_STATIC
] = "static",
1376 [KEEP_CONFIGURATION_YES
] = "yes",
1379 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);