1 /* SPDX-License-Identifier: LGPL-2.1+ */
4 #include <netinet/in.h>
5 #include <linux/netdevice.h>
8 #include "alloc-util.h"
9 #include "conf-files.h"
10 #include "conf-parser.h"
11 #include "dns-domain.h"
13 #include "hostname-util.h"
14 #include "in-addr-util.h"
15 #include "networkd-dhcp-server.h"
16 #include "network-internal.h"
17 #include "networkd-manager.h"
18 #include "networkd-network.h"
19 #include "parse-util.h"
20 #include "path-lookup.h"
22 #include "socket-util.h"
23 #include "stat-util.h"
24 #include "string-table.h"
25 #include "string-util.h"
30 /* Let's assume that anything above this number is a user misconfiguration. */
31 #define MAX_NTP_SERVERS 128
33 /* Set defaults following RFC7844 */
34 void network_apply_anonymize_if_set(Network
*network
) {
35 if (!network
->dhcp_anonymize
)
38 SHOULD NOT send the Host Name option */
39 network
->dhcp_send_hostname
= false;
40 /* RFC7844 section 3.:
41 MAY contain the Client Identifier option
43 clients MUST use client identifiers based solely
44 on the link-layer address */
45 /* NOTE: Using MAC, as it does not reveal extra information,
46 * and some servers might not answer if this option is not sent */
47 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
49 SHOULD NOT use the Vendor Class Identifier option */
50 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
51 /* RFC7844 section 3.6.:
52 The client intending to protect its privacy SHOULD only request a
53 minimal number of options in the PRL and SHOULD also randomly shuffle
54 the ordering of option codes in the PRL. If this random ordering
55 cannot be implemented, the client MAY order the option codes in the
56 PRL by option code number (lowest to highest).
58 /* NOTE: dhcp_use_mtu is false by default,
59 * though it was not initiallized to any value in network_load_one.
60 * Maybe there should be another var called *send*?
61 * (to use the MTU sent by the server but to do not send
62 * the option in the PRL). */
63 network
->dhcp_use_mtu
= false;
64 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
65 * but this is needed to use them. */
66 network
->dhcp_use_routes
= true;
67 /* RFC7844 section 3.6.
68 * same comments as previous option */
69 network
->dhcp_use_timezone
= false;
72 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
73 const char *kind_string
;
77 /* For test-networkd-conf, the check must be earlier than the assertions. */
82 assert(network
->manager
);
83 assert(network
->filename
);
86 if (kind
== _NETDEV_KIND_TUNNEL
)
87 kind_string
= "tunnel";
89 kind_string
= netdev_kind_to_string(kind
);
91 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
92 "%s: Invalid NetDev kind of %s, ignoring assignment.",
93 network
->filename
, name
);
96 r
= netdev_get(network
->manager
, name
, &netdev
);
98 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
99 network
->filename
, name
);
101 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
108 NETDEV_KIND_IP6GRETAP
,
112 NETDEV_KIND_ERSPAN
)))
113 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
114 "%s: NetDev %s is not a %s, ignoring assignment",
115 network
->filename
, name
, kind_string
);
117 *ret_netdev
= netdev_ref(netdev
);
121 static int network_resolve_stacked_netdevs(Network
*network
) {
128 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
129 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
131 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
135 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
139 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
141 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
142 network
->filename
, (const char *) name
);
150 int network_verify(Network
*network
) {
151 RoutePrefix
*route_prefix
, *route_prefix_next
;
152 RoutingPolicyRule
*rule
, *rule_next
;
153 Neighbor
*neighbor
, *neighbor_next
;
154 AddressLabel
*label
, *label_next
;
155 NextHop
*nexthop
, *nextnop_next
;
156 Address
*address
, *address_next
;
157 Prefix
*prefix
, *prefix_next
;
158 Route
*route
, *route_next
;
159 FdbEntry
*fdb
, *fdb_next
;
164 assert(network
->filename
);
166 if (set_isempty(network
->match_mac
) && set_isempty(network
->match_permanent_mac
) &&
167 strv_isempty(network
->match_path
) && strv_isempty(network
->match_driver
) &&
168 strv_isempty(network
->match_type
) && strv_isempty(network
->match_name
) &&
169 strv_isempty(network
->match_property
) && strv_isempty(network
->match_ssid
) && !network
->conditions
)
170 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
171 "%s: No valid settings found in the [Match] section, ignoring file. "
172 "To match all interfaces, add Name=* in the [Match] section.",
175 /* skip out early if configuration does not match the environment */
176 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
177 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
178 "%s: Conditions in the file do not match the system environment, skipping.",
181 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
182 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
183 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
184 (void) network_resolve_stacked_netdevs(network
);
186 /* Free unnecessary entries. */
187 network
->bond_name
= mfree(network
->bond_name
);
188 network
->bridge_name
= mfree(network
->bridge_name
);
189 network
->vrf_name
= mfree(network
->vrf_name
);
190 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
193 /* Bonding slave does not support addressing. */
194 if (network
->ipv6_accept_ra
> 0) {
195 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
197 network
->ipv6_accept_ra
= 0;
199 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
200 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
202 network
->link_local
= ADDRESS_FAMILY_NO
;
204 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
205 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
207 network
->dhcp
= ADDRESS_FAMILY_NO
;
209 if (network
->dhcp_server
) {
210 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
212 network
->dhcp_server
= false;
214 if (network
->n_static_addresses
> 0) {
215 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
217 while ((address
= network
->static_addresses
))
218 address_free(address
);
220 if (network
->n_static_routes
> 0) {
221 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
223 while ((route
= network
->static_routes
))
228 if (network
->link_local
< 0)
229 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
231 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
232 if (network
->ipv6_accept_ra
> 0) {
233 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
234 "Disabling IPv6AcceptRA=.", network
->filename
);
235 network
->ipv6_accept_ra
= false;
238 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
239 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
240 "Disabling DHCPv6 client.", network
->filename
);
241 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
244 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
245 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
246 "Disabling IPv6PrefixDelegation=.", network
->filename
);
247 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
251 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
252 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
253 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
254 "Disabling the fallback assignment.", network
->filename
);
255 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
258 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
259 network
->ipv6_accept_ra
= false;
261 /* IPMasquerade=yes implies IPForward=yes */
262 if (network
->ip_masquerade
)
263 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
265 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
266 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
267 "Disabling UseMTU=.", network
->filename
);
268 network
->dhcp_use_mtu
= false;
271 if (network
->dhcp_use_gateway
< 0)
272 network
->dhcp_use_gateway
= network
->dhcp_use_routes
;
274 if (network
->ignore_carrier_loss
< 0)
275 network
->ignore_carrier_loss
= network
->configure_without_carrier
;
277 if (network
->dhcp_critical
>= 0) {
278 if (network
->keep_configuration
>= 0)
279 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
280 "Ignoring CriticalConnection=.", network
->filename
);
281 else if (network
->dhcp_critical
)
282 /* CriticalConnection=yes also preserve foreign static configurations. */
283 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
285 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
288 if (network
->keep_configuration
< 0)
289 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
291 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
292 if (address_section_verify(address
) < 0)
293 address_free(address
);
295 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
296 if (route_section_verify(route
, network
) < 0)
299 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
300 if (nexthop_section_verify(nexthop
) < 0)
301 nexthop_free(nexthop
);
303 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
304 if (section_is_invalid(fdb
->section
))
307 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
308 if (neighbor_section_verify(neighbor
) < 0)
309 neighbor_free(neighbor
);
311 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
312 if (section_is_invalid(label
->section
))
313 address_label_free(label
);
315 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
316 if (section_is_invalid(prefix
->section
))
319 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
320 if (section_is_invalid(route_prefix
->section
))
321 route_prefix_free(route_prefix
);
323 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
324 if (routing_policy_rule_section_verify(rule
) < 0)
325 routing_policy_rule_free(rule
);
327 bool has_root
= false, has_clsact
= false;
328 ORDERED_HASHMAP_FOREACH(tc
, network
->tc_by_section
, i
)
329 if (traffic_control_section_verify(tc
, &has_root
, &has_clsact
) < 0)
330 traffic_control_free(tc
);
335 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
336 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
337 _cleanup_(network_unrefp
) Network
*network
= NULL
;
338 _cleanup_strv_free_
char **dropins
= NULL
;
339 _cleanup_fclose_
FILE *file
= NULL
;
340 const char *dropin_dirname
;
347 file
= fopen(filename
, "re");
355 if (null_or_empty_fd(fileno(file
))) {
356 log_debug("Skipping empty file: %s", filename
);
360 fname
= strdup(filename
);
364 name
= strdup(basename(filename
));
368 d
= strrchr(name
, '.');
374 dropin_dirname
= strjoina(name
, ".network.d");
376 network
= new(Network
, 1);
380 *network
= (Network
) {
381 .filename
= TAKE_PTR(fname
),
382 .name
= TAKE_PTR(name
),
387 .required_for_online
= true,
388 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
389 .dhcp
= ADDRESS_FAMILY_NO
,
391 .dhcp_use_ntp
= true,
392 .dhcp_use_sip
= true,
393 .dhcp_use_dns
= true,
394 .dhcp_use_hostname
= true,
395 .dhcp_use_routes
= true,
396 .dhcp_use_gateway
= -1,
397 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
398 .dhcp_send_hostname
= true,
399 .dhcp_send_release
= true,
400 /* To enable/disable RFC7844 Anonymity Profiles */
401 .dhcp_anonymize
= false,
402 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
403 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
404 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
405 .dhcp_route_table
= RT_TABLE_MAIN
,
406 .dhcp_route_table_set
= false,
407 /* NOTE: from man: UseMTU=... Defaults to false*/
408 .dhcp_use_mtu
= false,
409 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
410 .dhcp_use_timezone
= false,
411 .rapid_commit
= true,
413 .dhcp6_route_metric
= DHCP_ROUTE_METRIC
,
414 .dhcp6_use_ntp
= true,
415 .dhcp6_use_dns
= true,
417 .dhcp6_pd_assign_prefix
= true,
419 .dhcp_server_emit_dns
= true,
420 .dhcp_server_emit_ntp
= true,
421 .dhcp_server_emit_sip
= true,
422 .dhcp_server_emit_router
= true,
423 .dhcp_server_emit_timezone
= true,
425 .router_prefix_subnet_id
= -1,
426 .router_emit_dns
= true,
427 .router_emit_domains
= true,
432 .allow_port_to_be_root
= -1,
434 .multicast_flood
= -1,
435 .multicast_to_unicast
= -1,
436 .neighbor_suppression
= -1,
438 .bridge_proxy_arp
= -1,
439 .bridge_proxy_arp_wifi
= -1,
440 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
441 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
443 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
445 .dns_default_route
= -1,
446 .llmnr
= RESOLVE_SUPPORT_YES
,
447 .mdns
= RESOLVE_SUPPORT_NO
,
448 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
449 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
451 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
452 .link_local
= _ADDRESS_FAMILY_INVALID
,
454 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
455 .ipv6_accept_ra
= -1,
456 .ipv6_dad_transmits
= -1,
457 .ipv6_hop_limit
= -1,
458 .ipv6_proxy_ndp
= -1,
459 .duid
.type
= _DUID_TYPE_INVALID
,
464 .ipv6_accept_ra_use_dns
= true,
465 .ipv6_accept_ra_use_autonomous_prefix
= true,
466 .ipv6_accept_ra_use_onlink_prefix
= true,
467 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
468 .ipv6_accept_ra_route_table_set
= false,
469 .ipv6_accept_ra_start_dhcp6_client
= true,
471 .configure_without_carrier
= false,
472 .ignore_carrier_loss
= -1,
473 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
474 .ipv6_address_gen_mode
= _LINK_IPV6_ADDRESS_GEN_MODE_INVALID
,
475 .can_triple_sampling
= -1,
476 .can_termination
= -1,
477 .ip_service_type
= -1,
480 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
487 "RoutingPolicyRule\0"
490 "DHCP\0" /* compat */
495 "IPv6NDPProxyAddress\0"
499 "IPv6PrefixDelegation\0"
503 "TrafficControlQueueingDiscipline\0"
509 "DeficitRoundRobinScheduler\0"
510 "DeficitRoundRobinSchedulerClass\0"
515 "FairQueueingControlledDelay\0"
516 "GenericRandomEarlyDetection\0"
517 "HeavyHitterFilter\0"
518 "HierarchyTokenBucket\0"
519 "HierarchyTokenBucketClass\0"
522 "StochasticFairBlue\0"
523 "StochasticFairnessQueueing\0"
524 "TokenBucketFilter\0"
525 "TrivialLinkEqualizer\0",
526 config_item_perf_lookup
, network_network_gperf_lookup
,
527 CONFIG_PARSE_WARN
, network
, &dropins
);
531 network_apply_anonymize_if_set(network
);
533 r
= network_add_ipv4ll_route(network
);
535 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
537 r
= network_add_default_route_on_device(network
);
539 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
543 if (stat(filename
, &stats
) >= 0)
544 network
->timestamp
= timespec_load(&stats
.st_mtim
);
547 STRV_FOREACH(f
, dropins
) {
550 if (stat(*f
, &stats
) < 0) {
551 network
->timestamp
= 0;
555 t
= timespec_load(&stats
.st_mtim
);
556 if (t
> network
->timestamp
)
557 network
->timestamp
= t
;
560 if (network_verify(network
) < 0)
561 /* Ignore .network files that do not match the conditions. */
564 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
568 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
576 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
577 _cleanup_strv_free_
char **files
= NULL
;
583 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
585 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
587 return log_error_errno(r
, "Failed to enumerate network files: %m");
589 STRV_FOREACH(f
, files
) {
590 r
= network_load_one(manager
, networks
, *f
);
592 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
598 int network_reload(Manager
*manager
) {
599 OrderedHashmap
*new_networks
= NULL
;
606 r
= network_load(manager
, &new_networks
);
610 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
611 r
= network_get_by_name(manager
, n
->name
, &old
);
613 continue; /* The .network file is new. */
615 if (n
->timestamp
!= old
->timestamp
)
616 continue; /* The .network file is modified. */
618 if (!streq(n
->filename
, old
->filename
))
621 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
629 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
630 manager
->networks
= new_networks
;
635 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
640 static Network
*network_free(Network
*network
) {
641 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
642 RoutePrefix
*route_prefix
;
643 RoutingPolicyRule
*rule
;
655 free(network
->filename
);
657 set_free_free(network
->match_mac
);
658 set_free_free(network
->match_permanent_mac
);
659 strv_free(network
->match_path
);
660 strv_free(network
->match_driver
);
661 strv_free(network
->match_type
);
662 strv_free(network
->match_name
);
663 strv_free(network
->match_property
);
664 strv_free(network
->match_wlan_iftype
);
665 strv_free(network
->match_ssid
);
666 set_free_free(network
->match_bssid
);
667 condition_free_list(network
->conditions
);
669 free(network
->description
);
670 free(network
->dhcp_vendor_class_identifier
);
671 free(network
->dhcp_mudurl
);
672 strv_free(network
->dhcp_user_class
);
673 free(network
->dhcp_hostname
);
674 set_free(network
->dhcp_black_listed_ip
);
675 set_free(network
->dhcp_request_options
);
676 set_free(network
->dhcp6_request_options
);
678 free(network
->dhcp6_mudurl
);
679 strv_free(network
->dhcp6_user_class
);
680 strv_free(network
->dhcp6_vendor_class
);
682 if (network
->dhcp_acd
)
683 sd_ipv4acd_unref(network
->dhcp_acd
);
685 strv_free(network
->ntp
);
687 strv_free(network
->sip
);
688 strv_free(network
->smtp
);
689 ordered_set_free_free(network
->search_domains
);
690 ordered_set_free_free(network
->route_domains
);
691 strv_free(network
->bind_carrier
);
693 ordered_set_free_free(network
->router_search_domains
);
694 free(network
->router_dns
);
695 set_free_free(network
->ndisc_black_listed_prefix
);
697 free(network
->bridge_name
);
698 free(network
->bond_name
);
699 free(network
->vrf_name
);
700 hashmap_free_free_key(network
->stacked_netdev_names
);
701 netdev_unref(network
->bridge
);
702 netdev_unref(network
->bond
);
703 netdev_unref(network
->vrf
);
704 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
706 while ((route
= network
->static_routes
))
709 while ((nexthop
= network
->static_nexthops
))
710 nexthop_free(nexthop
);
712 while ((address
= network
->static_addresses
))
713 address_free(address
);
715 while ((fdb_entry
= network
->static_fdb_entries
))
716 fdb_entry_free(fdb_entry
);
718 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
719 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
721 while ((neighbor
= network
->neighbors
))
722 neighbor_free(neighbor
);
724 while ((label
= network
->address_labels
))
725 address_label_free(label
);
727 while ((prefix
= network
->static_prefixes
))
730 while ((route_prefix
= network
->static_route_prefixes
))
731 route_prefix_free(route_prefix
);
733 while ((rule
= network
->rules
))
734 routing_policy_rule_free(rule
);
736 hashmap_free(network
->addresses_by_section
);
737 hashmap_free(network
->routes_by_section
);
738 hashmap_free(network
->nexthops_by_section
);
739 hashmap_free(network
->fdb_entries_by_section
);
740 hashmap_free(network
->neighbors_by_section
);
741 hashmap_free(network
->address_labels_by_section
);
742 hashmap_free(network
->prefixes_by_section
);
743 hashmap_free(network
->route_prefixes_by_section
);
744 hashmap_free(network
->rules_by_section
);
745 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
747 if (network
->manager
&&
748 network
->manager
->duids_requesting_uuid
)
749 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
753 free(network
->dhcp_server_timezone
);
754 free(network
->dhcp_server_dns
);
755 free(network
->dhcp_server_ntp
);
756 free(network
->dhcp_server_sip
);
757 free(network
->dhcp_server_pop3
);
758 free(network
->dhcp_server_smtp
);
759 free(network
->dhcp_server_lpr
);
761 set_free_free(network
->dnssec_negative_trust_anchors
);
763 free(network
->lldp_mud
);
765 ordered_hashmap_free(network
->dhcp_client_send_options
);
766 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
767 ordered_hashmap_free(network
->dhcp_server_send_options
);
768 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
769 ordered_hashmap_free(network
->ipv6_tokens
);
770 ordered_hashmap_free(network
->dhcp6_client_send_options
);
771 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
773 return mfree(network
);
776 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
778 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
785 network
= ordered_hashmap_get(manager
->networks
, name
);
794 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
795 const char *ifname
, char * const *alternative_names
,
796 const struct ether_addr
*address
, const struct ether_addr
*permanent_address
,
797 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
805 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
806 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
807 network
->match_path
, network
->match_driver
,
808 network
->match_type
, network
->match_name
, network
->match_property
,
809 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
810 iftype
, device
, address
, permanent_address
,
811 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
812 if (network
->match_name
&& device
) {
814 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
816 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
817 (void) safe_atou8(attr
, &name_assign_type
);
819 if (name_assign_type
== NET_NAME_ENUM
)
820 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
821 ifname
, network
->filename
);
823 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
825 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
836 int network_apply(Network
*network
, Link
*link
) {
840 link
->network
= network_ref(network
);
842 if (network
->n_dns
> 0 ||
843 !strv_isempty(network
->ntp
) ||
844 !ordered_set_isempty(network
->search_domains
) ||
845 !ordered_set_isempty(network
->route_domains
))
851 bool network_has_static_ipv6_configurations(Network
*network
) {
859 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
860 if (address
->family
== AF_INET6
)
863 LIST_FOREACH(routes
, route
, network
->static_routes
)
864 if (route
->family
== AF_INET6
)
867 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
868 if (fdb
->family
== AF_INET6
)
871 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
872 if (neighbor
->family
== AF_INET6
)
875 if (!LIST_IS_EMPTY(network
->address_labels
))
878 if (!LIST_IS_EMPTY(network
->static_prefixes
))
884 int config_parse_stacked_netdev(const char *unit
,
885 const char *filename
,
888 unsigned section_line
,
894 _cleanup_free_
char *name
= NULL
;
895 NetDevKind kind
= ltype
;
904 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
905 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
906 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
909 if (!ifname_valid(rvalue
)) {
910 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
911 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
915 name
= strdup(rvalue
);
919 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
923 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
925 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
926 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
928 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
929 "NetDev '%s' specified twice, ignoring.", name
);
936 int config_parse_domains(
938 const char *filename
,
941 unsigned section_line
,
956 if (isempty(rvalue
)) {
957 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
958 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
964 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
968 r
= extract_first_word(&p
, &w
, NULL
, 0);
970 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
971 "Failed to extract search or route domain, ignoring: %s", rvalue
);
977 is_route
= w
[0] == '~';
978 domain
= is_route
? w
+ 1 : w
;
980 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
981 /* If the root domain appears as is, or the special token "*" is found, we'll
982 * consider this as routing domain, unconditionally. */
984 domain
= "."; /* make sure we don't allow empty strings, thus write the root
987 r
= dns_name_normalize(domain
, 0, &normalized
);
989 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
990 "'%s' is not a valid domain name, ignoring.", domain
);
996 if (is_localhost(domain
)) {
997 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
998 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
1004 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
1005 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
1009 r
= ordered_set_put_strdup(*set
, domain
);
1017 int config_parse_ipv6token(
1019 const char *filename
,
1021 const char *section
,
1022 unsigned section_line
,
1029 union in_addr_union buffer
;
1030 struct in6_addr
*token
= data
;
1038 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
1040 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1041 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1045 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1046 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1047 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1051 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1052 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1053 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1057 *token
= buffer
.in6
;
1062 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1063 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1064 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1065 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1068 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1069 IPV6_PRIVACY_EXTENSIONS_YES
);
1071 int config_parse_ipv6_privacy_extensions(
1073 const char *filename
,
1075 const char *section
,
1076 unsigned section_line
,
1083 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1088 assert(ipv6_privacy_extensions
);
1090 s
= ipv6_privacy_extensions_from_string(rvalue
);
1092 if (streq(rvalue
, "kernel"))
1093 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1095 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1096 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1101 *ipv6_privacy_extensions
= s
;
1106 int config_parse_hostname(
1108 const char *filename
,
1110 const char *section
,
1111 unsigned section_line
,
1118 _cleanup_free_
char *hn
= NULL
;
1119 char **hostname
= data
;
1126 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1130 if (!hostname_is_valid(hn
, false)) {
1131 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1132 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1136 r
= dns_name_is_valid(hn
);
1138 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1139 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1143 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1144 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1148 return free_and_replace(*hostname
, hn
);
1151 int config_parse_timezone(
1153 const char *filename
,
1155 const char *section
,
1156 unsigned section_line
,
1163 _cleanup_free_
char *tz
= NULL
;
1164 char **datap
= data
;
1171 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1175 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1176 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1177 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1181 return free_and_replace(*datap
, tz
);
1184 int config_parse_dns(
1186 const char *filename
,
1188 const char *section
,
1189 unsigned section_line
,
1196 Network
*n
= userdata
;
1204 _cleanup_free_
char *w
= NULL
;
1205 union in_addr_union a
;
1206 struct in_addr_data
*m
;
1209 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1213 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1214 "Invalid syntax, ignoring: %s", rvalue
);
1220 r
= in_addr_from_string_auto(w
, &family
, &a
);
1222 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1223 "Failed to parse dns server address, ignoring: %s", w
);
1227 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1231 m
[n
->n_dns
++] = (struct in_addr_data
) {
1242 int config_parse_dnssec_negative_trust_anchors(
1244 const char *filename
,
1246 const char *section
,
1247 unsigned section_line
,
1254 const char *p
= rvalue
;
1262 if (isempty(rvalue
)) {
1263 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1268 _cleanup_free_
char *w
= NULL
;
1270 r
= extract_first_word(&p
, &w
, NULL
, 0);
1272 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1273 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1279 r
= dns_name_is_valid(w
);
1281 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1282 "%s is not a valid domain name, ignoring.", w
);
1286 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1290 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1300 int config_parse_ntp(
1302 const char *filename
,
1304 const char *section
,
1305 unsigned section_line
,
1319 if (isempty(rvalue
)) {
1325 _cleanup_free_
char *w
= NULL
;
1327 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1331 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1332 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1338 r
= dns_name_is_valid_or_address(w
);
1340 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1341 "%s is not a valid domain name or IP address, ignoring.", w
);
1345 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1346 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1347 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1348 MAX_NTP_SERVERS
, w
);
1352 r
= strv_consume(l
, TAKE_PTR(w
));
1360 int config_parse_required_for_online(
1362 const char *filename
,
1364 const char *section
,
1365 unsigned section_line
,
1372 Network
*network
= data
;
1373 LinkOperationalStateRange range
;
1374 bool required
= true;
1377 if (isempty(rvalue
)) {
1378 network
->required_for_online
= true;
1379 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1383 r
= parse_operational_state_range(rvalue
, &range
);
1385 r
= parse_boolean(rvalue
);
1387 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1388 "Failed to parse %s= setting, ignoring assignment: %s",
1394 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1397 network
->required_for_online
= required
;
1398 network
->required_operstate_for_online
= range
;
1403 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1404 "Failed to parse KeepConfiguration= setting");
1406 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1407 [KEEP_CONFIGURATION_NO
] = "no",
1408 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1409 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1410 [KEEP_CONFIGURATION_STATIC
] = "static",
1411 [KEEP_CONFIGURATION_YES
] = "yes",
1414 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);