1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
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 "net-condition.h"
16 #include "netdev/macvlan.h"
17 #include "networkd-address-label.h"
18 #include "networkd-address.h"
19 #include "networkd-bridge-fdb.h"
20 #include "networkd-bridge-mdb.h"
21 #include "networkd-dhcp-common.h"
22 #include "networkd-dhcp-server-static-lease.h"
23 #include "networkd-dhcp-server.h"
24 #include "networkd-ipv6-proxy-ndp.h"
25 #include "networkd-manager.h"
26 #include "networkd-ndisc.h"
27 #include "networkd-neighbor.h"
28 #include "networkd-network.h"
29 #include "networkd-nexthop.h"
30 #include "networkd-radv.h"
31 #include "networkd-route.h"
32 #include "networkd-routing-policy-rule.h"
33 #include "networkd-sriov.h"
34 #include "parse-util.h"
35 #include "path-lookup.h"
37 #include "radv-internal.h"
39 #include "socket-util.h"
40 #include "stat-util.h"
41 #include "string-table.h"
42 #include "string-util.h"
46 /* Let's assume that anything above this number is a user misconfiguration. */
47 #define MAX_NTP_SERVERS 128U
49 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret
) {
50 const char *kind_string
;
54 /* For test-networkd-conf, the check must be earlier than the assertions. */
59 assert(network
->manager
);
60 assert(network
->filename
);
63 if (kind
== _NETDEV_KIND_TUNNEL
)
64 kind_string
= "tunnel";
66 kind_string
= netdev_kind_to_string(kind
);
68 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
69 "%s: Invalid NetDev kind of %s, ignoring assignment.",
70 network
->filename
, name
);
73 r
= netdev_get(network
->manager
, name
, &netdev
);
75 return log_warning_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
76 network
->filename
, name
);
78 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
84 NETDEV_KIND_IP6GRETAP
,
90 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
91 "%s: NetDev %s is not a %s, ignoring assignment",
92 network
->filename
, name
, kind_string
);
94 *ret
= netdev_ref(netdev
);
98 static int network_resolve_stacked_netdevs(Network
*network
) {
104 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
) {
105 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
107 if (network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
) <= 0)
110 r
= hashmap_ensure_put(&network
->stacked_netdevs
, &string_hash_ops
, netdev
->ifname
, netdev
);
114 log_warning_errno(r
, "%s: Failed to add NetDev '%s' to network, ignoring: %m",
115 network
->filename
, (const char *) name
);
123 int network_verify(Network
*network
) {
127 assert(network
->manager
);
128 assert(network
->filename
);
130 if (net_match_is_empty(&network
->match
) && !network
->conditions
)
131 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
132 "%s: No valid settings found in the [Match] section, ignoring file. "
133 "To match all interfaces, add Name=* in the [Match] section.",
136 /* skip out early if configuration does not match the environment */
137 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
138 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
139 "%s: Conditions in the file do not match the system environment, skipping.",
142 if (network
->keep_master
) {
143 if (network
->batadv_name
)
144 log_warning("%s: BatmanAdvanced= set with KeepMaster= enabled, ignoring BatmanAdvanced=.",
146 if (network
->bond_name
)
147 log_warning("%s: Bond= set with KeepMaster= enabled, ignoring Bond=.",
149 if (network
->bridge_name
)
150 log_warning("%s: Bridge= set with KeepMaster= enabled, ignoring Bridge=.",
152 if (network
->vrf_name
)
153 log_warning("%s: VRF= set with KeepMaster= enabled, ignoring VRF=.",
156 network
->batadv_name
= mfree(network
->batadv_name
);
157 network
->bond_name
= mfree(network
->bond_name
);
158 network
->bridge_name
= mfree(network
->bridge_name
);
159 network
->vrf_name
= mfree(network
->vrf_name
);
162 (void) network_resolve_netdev_one(network
, network
->batadv_name
, NETDEV_KIND_BATADV
, &network
->batadv
);
163 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
164 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
165 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
166 r
= network_resolve_stacked_netdevs(network
);
170 /* Free unnecessary entries. */
171 network
->batadv_name
= mfree(network
->batadv_name
);
172 network
->bond_name
= mfree(network
->bond_name
);
173 network
->bridge_name
= mfree(network
->bridge_name
);
174 network
->vrf_name
= mfree(network
->vrf_name
);
175 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
178 /* Bonding slave does not support addressing. */
179 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
180 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
182 network
->link_local
= ADDRESS_FAMILY_NO
;
184 if (network
->dhcp_server
) {
185 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
187 network
->dhcp_server
= false;
189 if (!ordered_hashmap_isempty(network
->addresses_by_section
))
190 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
192 if (!hashmap_isempty(network
->routes_by_section
))
193 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
196 network
->addresses_by_section
= ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
197 network
->routes_by_section
= hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
200 if (network
->link_local
< 0) {
201 network
->link_local
= ADDRESS_FAMILY_IPV6
;
203 if (network
->keep_master
|| network
->bridge
)
204 network
->link_local
= ADDRESS_FAMILY_NO
;
208 HASHMAP_FOREACH(netdev
, network
->stacked_netdevs
) {
211 if (netdev
->kind
== NETDEV_KIND_MACVLAN
)
213 else if (netdev
->kind
== NETDEV_KIND_MACVTAP
)
220 if (m
->mode
== NETDEV_MACVLAN_MODE_PASSTHRU
)
221 network
->link_local
= ADDRESS_FAMILY_NO
;
223 /* There won't be a passthru MACVLAN/MACVTAP if there's already one in another mode */
229 if (network
->ipv6ll_address_gen_mode
== IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
)
230 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_IPV6
, false);
232 if (in6_addr_is_set(&network
->ipv6ll_stable_secret
) &&
233 network
->ipv6ll_address_gen_mode
< 0)
234 network
->ipv6ll_address_gen_mode
= IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
;
236 /* IPMasquerade implies IPForward */
237 network
->ip_forward
|= network
->ip_masquerade
;
239 network_adjust_ipv6_proxy_ndp(network
);
240 network_adjust_ipv6_accept_ra(network
);
241 network_adjust_dhcp(network
);
242 network_adjust_radv(network
);
243 network_adjust_bridge_vlan(network
);
245 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
246 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
247 "Disabling UseMTU=.", network
->filename
);
248 network
->dhcp_use_mtu
= false;
251 if (network
->dhcp_critical
>= 0) {
252 if (network
->keep_configuration
>= 0) {
253 if (network
->manager
->keep_configuration
< 0)
254 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
255 "Ignoring CriticalConnection=.", network
->filename
);
256 } else if (network
->dhcp_critical
)
257 /* CriticalConnection=yes also preserve foreign static configurations. */
258 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
260 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
263 if (!strv_isempty(network
->bind_carrier
)) {
264 if (!IN_SET(network
->activation_policy
, _ACTIVATION_POLICY_INVALID
, ACTIVATION_POLICY_BOUND
))
265 log_warning("%s: ActivationPolicy=bound is required with BindCarrier=. "
266 "Setting ActivationPolicy=bound.", network
->filename
);
267 network
->activation_policy
= ACTIVATION_POLICY_BOUND
;
268 } else if (network
->activation_policy
== ACTIVATION_POLICY_BOUND
) {
269 log_warning("%s: ActivationPolicy=bound requires BindCarrier=. "
270 "Ignoring ActivationPolicy=bound.", network
->filename
);
271 network
->activation_policy
= ACTIVATION_POLICY_UP
;
274 if (network
->activation_policy
== _ACTIVATION_POLICY_INVALID
)
275 network
->activation_policy
= ACTIVATION_POLICY_UP
;
277 if (network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_UP
) {
278 if (network
->ignore_carrier_loss_set
&& network
->ignore_carrier_loss_usec
< USEC_INFINITY
)
279 log_warning("%s: IgnoreCarrierLoss=no or finite timespan conflicts with ActivationPolicy=always-up. "
280 "Setting IgnoreCarrierLoss=yes.", network
->filename
);
281 network
->ignore_carrier_loss_set
= true;
282 network
->ignore_carrier_loss_usec
= USEC_INFINITY
;
285 if (!network
->ignore_carrier_loss_set
) {
286 network
->ignore_carrier_loss_set
= true;
287 network
->ignore_carrier_loss_usec
= network
->configure_without_carrier
? USEC_INFINITY
: 0;
290 if (IN_SET(network
->activation_policy
, ACTIVATION_POLICY_DOWN
, ACTIVATION_POLICY_ALWAYS_DOWN
, ACTIVATION_POLICY_MANUAL
)) {
291 if (network
->required_for_online
< 0 ||
292 (network
->required_for_online
== true && network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_DOWN
)) {
293 log_debug("%s: Setting RequiredForOnline=no because ActivationPolicy=%s.", network
->filename
,
294 activation_policy_to_string(network
->activation_policy
));
295 network
->required_for_online
= false;
296 } else if (network
->required_for_online
== true)
297 log_warning("%s: RequiredForOnline=yes and ActivationPolicy=%s, "
298 "this may cause a delay at boot.", network
->filename
,
299 activation_policy_to_string(network
->activation_policy
));
302 if (network
->required_for_online
< 0)
303 network
->required_for_online
= true;
305 if (network
->keep_configuration
< 0)
306 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
308 if (network
->ipv6_proxy_ndp
== 0 && !set_isempty(network
->ipv6_proxy_ndp_addresses
)) {
309 log_warning("%s: IPv6ProxyNDP= is disabled. Ignoring IPv6ProxyNDPAddress=.", network
->filename
);
310 network
->ipv6_proxy_ndp_addresses
= set_free_free(network
->ipv6_proxy_ndp_addresses
);
313 r
= network_drop_invalid_addresses(network
);
315 return r
; /* network_drop_invalid_addresses() logs internally. */
316 network_drop_invalid_routes(network
);
317 network_drop_invalid_nexthops(network
);
318 network_drop_invalid_bridge_fdb_entries(network
);
319 network_drop_invalid_bridge_mdb_entries(network
);
320 network_drop_invalid_neighbors(network
);
321 network_drop_invalid_address_labels(network
);
322 network_drop_invalid_prefixes(network
);
323 network_drop_invalid_route_prefixes(network
);
324 network_drop_invalid_routing_policy_rules(network
);
325 network_drop_invalid_qdisc(network
);
326 network_drop_invalid_tclass(network
);
327 r
= sr_iov_drop_invalid_sections(UINT32_MAX
, network
->sr_iov_by_section
);
329 return r
; /* sr_iov_drop_invalid_sections() logs internally. */
330 network_drop_invalid_static_leases(network
);
332 network_adjust_dhcp_server(network
);
337 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
338 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
339 _cleanup_(network_unrefp
) Network
*network
= NULL
;
340 const char *dropin_dirname
;
347 r
= null_or_empty_path(filename
);
349 return log_warning_errno(r
, "Failed to check if \"%s\" is empty: %m", filename
);
351 log_debug("Skipping empty file: %s", filename
);
355 fname
= strdup(filename
);
359 name
= strdup(basename(filename
));
363 d
= strrchr(name
, '.');
365 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
), "Invalid file name: %s", filename
);
369 dropin_dirname
= strjoina(name
, ".network.d");
371 network
= new(Network
, 1);
375 *network
= (Network
) {
376 .filename
= TAKE_PTR(fname
),
377 .name
= TAKE_PTR(name
),
382 .required_for_online
= -1,
383 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
384 .activation_policy
= _ACTIVATION_POLICY_INVALID
,
391 .keep_configuration
= manager
->keep_configuration
,
393 .dhcp_duid
.type
= _DUID_TYPE_INVALID
,
395 .dhcp_use_ntp
= true,
396 .dhcp_routes_to_ntp
= true,
397 .dhcp_use_sip
= true,
398 .dhcp_use_captive_portal
= true,
399 .dhcp_use_dns
= true,
400 .dhcp_routes_to_dns
= true,
401 .dhcp_use_hostname
= true,
402 .dhcp_use_routes
= true,
403 .dhcp_use_gateway
= -1,
404 .dhcp_send_hostname
= true,
405 .dhcp_send_release
= true,
406 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
407 .dhcp_client_identifier
= _DHCP_CLIENT_ID_INVALID
,
408 .dhcp_route_table
= RT_TABLE_MAIN
,
409 .dhcp_ip_service_type
= -1,
410 .dhcp_broadcast
= -1,
412 .dhcp6_use_address
= true,
413 .dhcp6_use_pd_prefix
= true,
414 .dhcp6_use_dns
= true,
415 .dhcp6_use_hostname
= true,
416 .dhcp6_use_ntp
= true,
417 .dhcp6_use_captive_portal
= true,
418 .dhcp6_use_rapid_commit
= true,
419 .dhcp6_duid
.type
= _DUID_TYPE_INVALID
,
420 .dhcp6_client_start_mode
= _DHCP6_CLIENT_START_MODE_INVALID
,
421 .dhcp6_send_release
= true,
424 .dhcp_pd_announce
= true,
425 .dhcp_pd_assign
= true,
426 .dhcp_pd_manage_temporary_address
= true,
427 .dhcp_pd_subnet_id
= -1,
428 .dhcp_pd_route_metric
= DHCP6PD_ROUTE_METRIC
,
430 .dhcp_server_bind_to_interface
= true,
431 .dhcp_server_emit
[SD_DHCP_LEASE_DNS
].emit
= true,
432 .dhcp_server_emit
[SD_DHCP_LEASE_NTP
].emit
= true,
433 .dhcp_server_emit
[SD_DHCP_LEASE_SIP
].emit
= true,
434 .dhcp_server_emit_router
= true,
435 .dhcp_server_emit_timezone
= true,
437 .router_lifetime_usec
= RADV_DEFAULT_ROUTER_LIFETIME_USEC
,
438 .router_dns_lifetime_usec
= RADV_DEFAULT_VALID_LIFETIME_USEC
,
439 .router_emit_dns
= true,
440 .router_emit_domains
= true,
446 .allow_port_to_be_root
= -1,
448 .multicast_flood
= -1,
449 .multicast_to_unicast
= -1,
450 .neighbor_suppression
= -1,
452 .bridge_proxy_arp
= -1,
453 .bridge_proxy_arp_wifi
= -1,
454 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
455 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
457 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
458 .lldp_multicast_mode
= _SD_LLDP_MULTICAST_MODE_INVALID
,
460 .dns_default_route
= -1,
461 .llmnr
= RESOLVE_SUPPORT_YES
,
462 .mdns
= RESOLVE_SUPPORT_NO
,
463 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
464 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
466 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
467 .link_local
= _ADDRESS_FAMILY_INVALID
,
468 .ipv6ll_address_gen_mode
= _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID
,
470 .ipv4_accept_local
= -1,
471 .ipv4_route_localnet
= -1,
472 .ipv6_privacy_extensions
= _IPV6_PRIVACY_EXTENSIONS_INVALID
,
473 .ipv6_dad_transmits
= -1,
474 .ipv6_hop_limit
= -1,
475 .ipv6_proxy_ndp
= -1,
478 .ipv6_accept_ra
= -1,
479 .ipv6_accept_ra_use_dns
= true,
480 .ipv6_accept_ra_use_gateway
= true,
481 .ipv6_accept_ra_use_captive_portal
= true,
482 .ipv6_accept_ra_use_route_prefix
= true,
483 .ipv6_accept_ra_use_autonomous_prefix
= true,
484 .ipv6_accept_ra_use_onlink_prefix
= true,
485 .ipv6_accept_ra_use_mtu
= true,
486 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
487 .ipv6_accept_ra_route_metric_high
= IPV6RA_ROUTE_METRIC_HIGH
,
488 .ipv6_accept_ra_route_metric_medium
= IPV6RA_ROUTE_METRIC_MEDIUM
,
489 .ipv6_accept_ra_route_metric_low
= IPV6RA_ROUTE_METRIC_LOW
,
490 .ipv6_accept_ra_start_dhcp6_client
= IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
,
492 .can_termination
= -1,
494 .ipoib_mode
= _IP_OVER_INFINIBAND_MODE_INVALID
,
498 r
= config_parse_many(
499 STRV_MAKE_CONST(filename
), NETWORK_DIRS
, dropin_dirname
, /* root = */ NULL
,
507 "RoutingPolicyRule\0"
510 "DHCP\0" /* compat */
513 "DHCPv6PrefixDelegation\0" /* compat */
514 "DHCPPrefixDelegation\0"
516 "DHCPServerStaticLease\0"
518 "IPv6NDPProxyAddress\0"
524 "IPv6PrefixDelegation\0"
528 "TrafficControlQueueingDiscipline\0"
534 "DeficitRoundRobinScheduler\0"
535 "DeficitRoundRobinSchedulerClass\0"
536 "EnhancedTransmissionSelection\0"
538 "FairQueueingControlledDelay\0"
540 "GenericRandomEarlyDetection\0"
541 "HeavyHitterFilter\0"
542 "HierarchyTokenBucket\0"
543 "HierarchyTokenBucketClass\0"
549 "QuickFairQueueing\0"
550 "QuickFairQueueingClass\0"
551 "StochasticFairBlue\0"
552 "StochasticFairnessQueueing\0"
553 "TokenBucketFilter\0"
554 "TrivialLinkEqualizer\0",
555 config_item_perf_lookup
, network_network_gperf_lookup
,
558 &network
->stats_by_path
,
561 return r
; /* config_parse_many() logs internally. */
563 r
= network_add_ipv4ll_route(network
);
565 return log_warning_errno(r
, "%s: Failed to add IPv4LL route: %m", network
->filename
);
567 r
= network_add_default_route_on_device(network
);
569 return log_warning_errno(r
, "%s: Failed to add default route on device: %m",
572 r
= network_verify(network
);
574 return r
; /* network_verify() logs internally. */
576 r
= ordered_hashmap_ensure_put(networks
, &string_hash_ops
, network
->name
, network
);
578 return log_warning_errno(r
, "%s: Failed to store configuration into hashmap: %m", filename
);
584 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
585 _cleanup_strv_free_
char **files
= NULL
;
590 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
592 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
594 return log_error_errno(r
, "Failed to enumerate network files: %m");
596 STRV_FOREACH(f
, files
)
597 (void) network_load_one(manager
, networks
, *f
);
602 int network_reload(Manager
*manager
) {
603 OrderedHashmap
*new_networks
= NULL
;
609 r
= network_load(manager
, &new_networks
);
613 ORDERED_HASHMAP_FOREACH(n
, new_networks
) {
614 r
= network_get_by_name(manager
, n
->name
, &old
);
616 log_debug("Found new .network file: %s", n
->filename
);
620 if (!stats_by_path_equal(n
->stats_by_path
, old
->stats_by_path
)) {
621 log_debug("Found updated .network file: %s", n
->filename
);
625 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
633 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
634 manager
->networks
= new_networks
;
636 return manager_build_dhcp_pd_subnet_ids(manager
);
639 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
644 int manager_build_dhcp_pd_subnet_ids(Manager
*manager
) {
650 set_clear(manager
->dhcp_pd_subnet_ids
);
652 ORDERED_HASHMAP_FOREACH(n
, manager
->networks
) {
659 if (n
->dhcp_pd_subnet_id
< 0)
662 r
= set_ensure_put(&manager
->dhcp_pd_subnet_ids
, &uint64_hash_ops
, &n
->dhcp_pd_subnet_id
);
670 static Network
*network_free(Network
*network
) {
675 free(network
->filename
);
676 free(network
->description
);
677 strv_free(network
->dropins
);
678 hashmap_free(network
->stats_by_path
);
681 net_match_clear(&network
->match
);
682 condition_free_list(network
->conditions
);
685 strv_free(network
->bind_carrier
);
688 strv_free(network
->ntp
);
691 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
692 in_addr_full_free(network
->dns
[i
]);
694 ordered_set_free(network
->search_domains
);
695 ordered_set_free(network
->route_domains
);
696 set_free_free(network
->dnssec_negative_trust_anchors
);
699 free(network
->dhcp_server_relay_agent_circuit_id
);
700 free(network
->dhcp_server_relay_agent_remote_id
);
701 free(network
->dhcp_server_boot_server_name
);
702 free(network
->dhcp_server_boot_filename
);
703 free(network
->dhcp_server_timezone
);
704 free(network
->dhcp_server_uplink_name
);
705 for (sd_dhcp_lease_server_type_t t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
706 free(network
->dhcp_server_emit
[t
].addresses
);
707 ordered_hashmap_free(network
->dhcp_server_send_options
);
708 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
711 free(network
->dhcp_vendor_class_identifier
);
712 free(network
->dhcp_mudurl
);
713 free(network
->dhcp_hostname
);
714 free(network
->dhcp_label
);
715 set_free(network
->dhcp_deny_listed_ip
);
716 set_free(network
->dhcp_allow_listed_ip
);
717 strv_free(network
->dhcp_user_class
);
718 set_free(network
->dhcp_request_options
);
719 ordered_hashmap_free(network
->dhcp_client_send_options
);
720 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
721 free(network
->dhcp_netlabel
);
724 free(network
->dhcp6_mudurl
);
725 strv_free(network
->dhcp6_user_class
);
726 strv_free(network
->dhcp6_vendor_class
);
727 set_free(network
->dhcp6_request_options
);
728 ordered_hashmap_free(network
->dhcp6_client_send_options
);
729 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
730 free(network
->dhcp6_netlabel
);
733 free(network
->dhcp_pd_uplink_name
);
734 set_free(network
->dhcp_pd_tokens
);
735 free(network
->dhcp_pd_netlabel
);
737 /* Router advertisement */
738 ordered_set_free(network
->router_search_domains
);
739 free(network
->router_dns
);
740 free(network
->router_uplink_name
);
743 set_free(network
->ndisc_deny_listed_router
);
744 set_free(network
->ndisc_allow_listed_router
);
745 set_free(network
->ndisc_deny_listed_prefix
);
746 set_free(network
->ndisc_allow_listed_prefix
);
747 set_free(network
->ndisc_deny_listed_route_prefix
);
748 set_free(network
->ndisc_allow_listed_route_prefix
);
749 set_free(network
->ndisc_tokens
);
750 free(network
->ndisc_netlabel
);
753 free(network
->lldp_mudurl
);
756 free(network
->batadv_name
);
757 free(network
->bridge_name
);
758 free(network
->bond_name
);
759 free(network
->vrf_name
);
760 hashmap_free_free_key(network
->stacked_netdev_names
);
761 netdev_unref(network
->bridge
);
762 netdev_unref(network
->bond
);
763 netdev_unref(network
->vrf
);
764 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
767 set_free_free(network
->ipv6_proxy_ndp_addresses
);
768 ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
769 hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
770 hashmap_free_with_destructor(network
->nexthops_by_section
, nexthop_free
);
771 hashmap_free_with_destructor(network
->bridge_fdb_entries_by_section
, bridge_fdb_free
);
772 hashmap_free_with_destructor(network
->bridge_mdb_entries_by_section
, bridge_mdb_free
);
773 hashmap_free_with_destructor(network
->neighbors_by_section
, neighbor_free
);
774 hashmap_free_with_destructor(network
->address_labels_by_section
, address_label_free
);
775 hashmap_free_with_destructor(network
->prefixes_by_section
, prefix_free
);
776 hashmap_free_with_destructor(network
->route_prefixes_by_section
, route_prefix_free
);
777 hashmap_free_with_destructor(network
->rules_by_section
, routing_policy_rule_free
);
778 hashmap_free_with_destructor(network
->dhcp_static_leases_by_section
, dhcp_static_lease_free
);
779 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
780 hashmap_free_with_destructor(network
->qdiscs_by_section
, qdisc_free
);
781 hashmap_free_with_destructor(network
->tclasses_by_section
, tclass_free
);
783 return mfree(network
);
786 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
788 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
795 network
= ordered_hashmap_get(manager
->networks
, name
);
804 bool network_has_static_ipv6_configurations(Network
*network
) {
813 ORDERED_HASHMAP_FOREACH(address
, network
->addresses_by_section
)
814 if (address
->family
== AF_INET6
)
817 HASHMAP_FOREACH(route
, network
->routes_by_section
)
818 if (route
->family
== AF_INET6
)
821 HASHMAP_FOREACH(fdb
, network
->bridge_fdb_entries_by_section
)
822 if (fdb
->family
== AF_INET6
)
825 HASHMAP_FOREACH(mdb
, network
->bridge_mdb_entries_by_section
)
826 if (mdb
->family
== AF_INET6
)
829 HASHMAP_FOREACH(neighbor
, network
->neighbors_by_section
)
830 if (neighbor
->family
== AF_INET6
)
833 if (!hashmap_isempty(network
->address_labels_by_section
))
836 if (!hashmap_isempty(network
->prefixes_by_section
))
839 if (!hashmap_isempty(network
->route_prefixes_by_section
))
845 int config_parse_stacked_netdev(
847 const char *filename
,
850 unsigned section_line
,
857 _cleanup_free_
char *name
= NULL
;
858 NetDevKind kind
= ltype
;
859 Hashmap
**h
= ASSERT_PTR(data
);
875 _NETDEV_KIND_TUNNEL
));
877 if (!ifname_valid(rvalue
)) {
878 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
879 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
883 name
= strdup(rvalue
);
887 r
= hashmap_ensure_put(h
, &string_hash_ops
, name
, INT_TO_PTR(kind
));
891 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
892 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
894 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
895 "NetDev '%s' specified twice, ignoring.", name
);
902 int config_parse_domains(
904 const char *filename
,
907 unsigned section_line
,
914 Network
*n
= ASSERT_PTR(userdata
);
921 if (isempty(rvalue
)) {
922 n
->search_domains
= ordered_set_free(n
->search_domains
);
923 n
->route_domains
= ordered_set_free(n
->route_domains
);
927 for (const char *p
= rvalue
;;) {
928 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
932 r
= extract_first_word(&p
, &w
, NULL
, 0);
936 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
937 "Failed to extract search or route domain, ignoring: %s", rvalue
);
943 is_route
= w
[0] == '~';
944 domain
= is_route
? w
+ 1 : w
;
946 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
947 /* If the root domain appears as is, or the special token "*" is found, we'll
948 * consider this as routing domain, unconditionally. */
950 domain
= "."; /* make sure we don't allow empty strings, thus write the root
953 r
= dns_name_normalize(domain
, 0, &normalized
);
955 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
956 "'%s' is not a valid domain name, ignoring.", domain
);
962 if (is_localhost(domain
)) {
963 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
964 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
970 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
971 r
= ordered_set_put_strdup(set
, domain
);
979 int config_parse_timezone(
981 const char *filename
,
984 unsigned section_line
,
991 char **tz
= ASSERT_PTR(data
);
998 if (isempty(rvalue
)) {
1003 r
= verify_timezone(rvalue
, LOG_WARNING
);
1005 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1006 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1010 return free_and_strdup_warn(tz
, rvalue
);
1013 int config_parse_dns(
1015 const char *filename
,
1017 const char *section
,
1018 unsigned section_line
,
1025 Network
*n
= ASSERT_PTR(userdata
);
1032 if (isempty(rvalue
)) {
1033 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
1034 in_addr_full_free(n
->dns
[i
]);
1035 n
->dns
= mfree(n
->dns
);
1040 for (const char *p
= rvalue
;;) {
1041 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
1042 _cleanup_free_
char *w
= NULL
;
1043 struct in_addr_full
**m
;
1045 r
= extract_first_word(&p
, &w
, NULL
, 0);
1049 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1050 "Invalid syntax, ignoring: %s", rvalue
);
1056 r
= in_addr_full_new_from_string(w
, &dns
);
1058 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1059 "Failed to parse dns server address, ignoring: %s", w
);
1063 if (IN_SET(dns
->port
, 53, 853))
1066 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
1070 m
[n
->n_dns
++] = TAKE_PTR(dns
);
1075 int config_parse_dnssec_negative_trust_anchors(
1077 const char *filename
,
1079 const char *section
,
1080 unsigned section_line
,
1087 Set
**nta
= ASSERT_PTR(data
);
1094 if (isempty(rvalue
)) {
1095 *nta
= set_free_free(*nta
);
1099 for (const char *p
= rvalue
;;) {
1100 _cleanup_free_
char *w
= NULL
;
1102 r
= extract_first_word(&p
, &w
, NULL
, 0);
1106 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1107 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1113 r
= dns_name_is_valid(w
);
1115 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1116 "%s is not a valid domain name, ignoring.", w
);
1120 r
= set_ensure_consume(nta
, &dns_name_hash_ops
, TAKE_PTR(w
));
1126 int config_parse_ntp(
1128 const char *filename
,
1130 const char *section
,
1131 unsigned section_line
,
1138 char ***l
= ASSERT_PTR(data
);
1145 if (isempty(rvalue
)) {
1150 for (const char *p
= rvalue
;;) {
1151 _cleanup_free_
char *w
= NULL
;
1153 r
= extract_first_word(&p
, &w
, NULL
, 0);
1157 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1158 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1164 r
= dns_name_is_valid_or_address(w
);
1166 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1167 "%s is not a valid domain name or IP address, ignoring.", w
);
1171 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1172 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1173 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1174 MAX_NTP_SERVERS
, w
);
1178 r
= strv_consume(l
, TAKE_PTR(w
));
1184 int config_parse_required_for_online(
1186 const char *filename
,
1188 const char *section
,
1189 unsigned section_line
,
1196 Network
*network
= ASSERT_PTR(userdata
);
1197 LinkOperationalStateRange range
;
1198 bool required
= true;
1205 if (isempty(rvalue
)) {
1206 network
->required_for_online
= -1;
1207 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1211 r
= parse_operational_state_range(rvalue
, &range
);
1213 r
= parse_boolean(rvalue
);
1215 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1216 "Failed to parse %s= setting, ignoring assignment: %s",
1222 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1225 network
->required_for_online
= required
;
1226 network
->required_operstate_for_online
= range
;
1231 int config_parse_link_group(
1233 const char *filename
,
1235 const char *section
,
1236 unsigned section_line
,
1243 Network
*network
= ASSERT_PTR(userdata
);
1251 if (isempty(rvalue
)) {
1252 network
->group
= -1;
1256 r
= safe_atoi32(rvalue
, &group
);
1258 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1259 "Failed to parse Group=, ignoring assignment: %s", rvalue
);
1264 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1265 "Value of Group= must be in the range 0…2147483647, ignoring assignment: %s", rvalue
);
1269 network
->group
= group
;
1273 int config_parse_ignore_carrier_loss(
1275 const char *filename
,
1277 const char *section
,
1278 unsigned section_line
,
1285 Network
*network
= ASSERT_PTR(userdata
);
1293 if (isempty(rvalue
)) {
1294 network
->ignore_carrier_loss_set
= false;
1298 r
= parse_boolean(rvalue
);
1300 network
->ignore_carrier_loss_set
= true;
1301 network
->ignore_carrier_loss_usec
= r
> 0 ? USEC_INFINITY
: 0;
1305 r
= parse_sec(rvalue
, &usec
);
1307 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1308 "Failed to parse %s=, ignoring assignment: %s", lvalue
, rvalue
);
1312 network
->ignore_carrier_loss_set
= true;
1313 network
->ignore_carrier_loss_usec
= usec
;
1317 DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online
, link_required_address_family
, AddressFamily
,
1318 "Failed to parse RequiredFamilyForOnline= setting");
1320 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1321 "Failed to parse KeepConfiguration= setting");
1323 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1324 [KEEP_CONFIGURATION_NO
] = "no",
1325 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1326 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1327 [KEEP_CONFIGURATION_STATIC
] = "static",
1328 [KEEP_CONFIGURATION_YES
] = "yes",
1331 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1333 static const char* const activation_policy_table
[_ACTIVATION_POLICY_MAX
] = {
1334 [ACTIVATION_POLICY_UP
] = "up",
1335 [ACTIVATION_POLICY_ALWAYS_UP
] = "always-up",
1336 [ACTIVATION_POLICY_MANUAL
] = "manual",
1337 [ACTIVATION_POLICY_ALWAYS_DOWN
] = "always-down",
1338 [ACTIVATION_POLICY_DOWN
] = "down",
1339 [ACTIVATION_POLICY_BOUND
] = "bound",
1342 DEFINE_STRING_TABLE_LOOKUP(activation_policy
, ActivationPolicy
);
1343 DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy
, activation_policy
, ActivationPolicy
, "Failed to parse activation policy");