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-ipv6-proxy-ndp.h"
24 #include "networkd-manager.h"
25 #include "networkd-ndisc.h"
26 #include "networkd-neighbor.h"
27 #include "networkd-network.h"
28 #include "networkd-nexthop.h"
29 #include "networkd-radv.h"
30 #include "networkd-route.h"
31 #include "networkd-routing-policy-rule.h"
32 #include "networkd-sriov.h"
33 #include "parse-util.h"
34 #include "path-lookup.h"
36 #include "radv-internal.h"
38 #include "socket-util.h"
39 #include "stat-util.h"
40 #include "string-table.h"
41 #include "string-util.h"
45 /* Let's assume that anything above this number is a user misconfiguration. */
46 #define MAX_NTP_SERVERS 128U
48 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret
) {
49 const char *kind_string
;
53 /* For test-networkd-conf, the check must be earlier than the assertions. */
58 assert(network
->manager
);
59 assert(network
->filename
);
62 if (kind
== _NETDEV_KIND_TUNNEL
)
63 kind_string
= "tunnel";
65 kind_string
= netdev_kind_to_string(kind
);
67 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
68 "%s: Invalid NetDev kind of %s, ignoring assignment.",
69 network
->filename
, name
);
72 r
= netdev_get(network
->manager
, name
, &netdev
);
74 return log_warning_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
75 network
->filename
, name
);
77 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
83 NETDEV_KIND_IP6GRETAP
,
89 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
90 "%s: NetDev %s is not a %s, ignoring assignment",
91 network
->filename
, name
, kind_string
);
93 *ret
= netdev_ref(netdev
);
97 static int network_resolve_stacked_netdevs(Network
*network
) {
103 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
) {
104 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
106 if (network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
) <= 0)
109 r
= hashmap_ensure_put(&network
->stacked_netdevs
, &string_hash_ops
, netdev
->ifname
, netdev
);
113 log_warning_errno(r
, "%s: Failed to add NetDev '%s' to network, ignoring: %m",
114 network
->filename
, (const char *) name
);
122 int network_verify(Network
*network
) {
126 assert(network
->manager
);
127 assert(network
->filename
);
129 if (net_match_is_empty(&network
->match
) && !network
->conditions
)
130 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
131 "%s: No valid settings found in the [Match] section, ignoring file. "
132 "To match all interfaces, add Name=* in the [Match] section.",
135 /* skip out early if configuration does not match the environment */
136 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
137 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
138 "%s: Conditions in the file do not match the system environment, skipping.",
141 if (network
->keep_master
) {
142 if (network
->batadv_name
)
143 log_warning("%s: BatmanAdvanced= set with KeepMaster= enabled, ignoring BatmanAdvanced=.",
145 if (network
->bond_name
)
146 log_warning("%s: Bond= set with KeepMaster= enabled, ignoring Bond=.",
148 if (network
->bridge_name
)
149 log_warning("%s: Bridge= set with KeepMaster= enabled, ignoring Bridge=.",
151 if (network
->vrf_name
)
152 log_warning("%s: VRF= set with KeepMaster= enabled, ignoring VRF=.",
155 network
->batadv_name
= mfree(network
->batadv_name
);
156 network
->bond_name
= mfree(network
->bond_name
);
157 network
->bridge_name
= mfree(network
->bridge_name
);
158 network
->vrf_name
= mfree(network
->vrf_name
);
161 (void) network_resolve_netdev_one(network
, network
->batadv_name
, NETDEV_KIND_BATADV
, &network
->batadv
);
162 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
163 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
164 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
165 r
= network_resolve_stacked_netdevs(network
);
169 /* Free unnecessary entries. */
170 network
->batadv_name
= mfree(network
->batadv_name
);
171 network
->bond_name
= mfree(network
->bond_name
);
172 network
->bridge_name
= mfree(network
->bridge_name
);
173 network
->vrf_name
= mfree(network
->vrf_name
);
174 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
177 /* Bonding slave does not support addressing. */
178 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
179 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
181 network
->link_local
= ADDRESS_FAMILY_NO
;
183 if (!ordered_hashmap_isempty(network
->addresses_by_section
))
184 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
186 if (!hashmap_isempty(network
->routes_by_section
))
187 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
190 network
->addresses_by_section
= ordered_hashmap_free(network
->addresses_by_section
);
191 network
->routes_by_section
= hashmap_free(network
->routes_by_section
);
194 if (network
->link_local
< 0) {
195 network
->link_local
= ADDRESS_FAMILY_IPV6
;
197 if (network
->keep_master
|| network
->bridge
)
198 network
->link_local
= ADDRESS_FAMILY_NO
;
202 HASHMAP_FOREACH(netdev
, network
->stacked_netdevs
) {
205 if (netdev
->kind
== NETDEV_KIND_MACVLAN
)
207 else if (netdev
->kind
== NETDEV_KIND_MACVTAP
)
212 if (m
->mode
== NETDEV_MACVLAN_MODE_PASSTHRU
)
213 network
->link_local
= ADDRESS_FAMILY_NO
;
215 /* There won't be a passthru MACVLAN/MACVTAP if there's already one in another mode */
221 if (network
->ipv6ll_address_gen_mode
== IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
)
222 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_IPV6
, false);
224 if (in6_addr_is_set(&network
->ipv6ll_stable_secret
) &&
225 network
->ipv6ll_address_gen_mode
< 0)
226 network
->ipv6ll_address_gen_mode
= IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
;
228 network_adjust_ipv6_proxy_ndp(network
);
229 network_adjust_ndisc(network
);
230 network_adjust_dhcp(network
);
231 network_adjust_radv(network
);
232 network_adjust_bridge_vlan(network
);
234 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
235 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
236 "Disabling UseMTU=.", network
->filename
);
237 network
->dhcp_use_mtu
= false;
240 if (network
->dhcp_critical
>= 0) {
241 if (network
->keep_configuration
>= 0) {
242 if (network
->manager
->keep_configuration
< 0)
243 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
244 "Ignoring CriticalConnection=.", network
->filename
);
245 } else if (network
->dhcp_critical
)
246 /* CriticalConnection=yes also preserve foreign static configurations. */
247 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
249 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
252 if (!strv_isempty(network
->bind_carrier
)) {
253 if (!IN_SET(network
->activation_policy
, _ACTIVATION_POLICY_INVALID
, ACTIVATION_POLICY_BOUND
))
254 log_warning("%s: ActivationPolicy=bound is required with BindCarrier=. "
255 "Setting ActivationPolicy=bound.", network
->filename
);
256 network
->activation_policy
= ACTIVATION_POLICY_BOUND
;
257 } else if (network
->activation_policy
== ACTIVATION_POLICY_BOUND
) {
258 log_warning("%s: ActivationPolicy=bound requires BindCarrier=. "
259 "Ignoring ActivationPolicy=bound.", network
->filename
);
260 network
->activation_policy
= ACTIVATION_POLICY_UP
;
263 if (network
->activation_policy
== _ACTIVATION_POLICY_INVALID
)
264 network
->activation_policy
= ACTIVATION_POLICY_UP
;
266 if (network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_UP
) {
267 if (network
->ignore_carrier_loss_set
&& network
->ignore_carrier_loss_usec
< USEC_INFINITY
)
268 log_warning("%s: IgnoreCarrierLoss=no or finite timespan conflicts with ActivationPolicy=always-up. "
269 "Setting IgnoreCarrierLoss=yes.", network
->filename
);
270 network
->ignore_carrier_loss_set
= true;
271 network
->ignore_carrier_loss_usec
= USEC_INFINITY
;
274 if (!network
->ignore_carrier_loss_set
) /* Set implied default. */
275 network
->ignore_carrier_loss_usec
= network
->configure_without_carrier
? USEC_INFINITY
: 0;
277 if (IN_SET(network
->activation_policy
, ACTIVATION_POLICY_DOWN
, ACTIVATION_POLICY_ALWAYS_DOWN
, ACTIVATION_POLICY_MANUAL
)) {
278 if (network
->required_for_online
< 0 ||
279 (network
->required_for_online
== true && network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_DOWN
)) {
280 log_debug("%s: Setting RequiredForOnline=no because ActivationPolicy=%s.", network
->filename
,
281 activation_policy_to_string(network
->activation_policy
));
282 network
->required_for_online
= false;
283 } else if (network
->required_for_online
== true)
284 log_warning("%s: RequiredForOnline=yes and ActivationPolicy=%s, "
285 "this may cause a delay at boot.", network
->filename
,
286 activation_policy_to_string(network
->activation_policy
));
289 if (network
->required_for_online
< 0)
290 network
->required_for_online
= true;
292 if (network
->keep_configuration
< 0)
293 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
295 if (network
->ipv6_proxy_ndp
== 0 && !set_isempty(network
->ipv6_proxy_ndp_addresses
)) {
296 log_warning("%s: IPv6ProxyNDP= is disabled. Ignoring IPv6ProxyNDPAddress=.", network
->filename
);
297 network
->ipv6_proxy_ndp_addresses
= set_free_free(network
->ipv6_proxy_ndp_addresses
);
300 r
= network_drop_invalid_addresses(network
);
302 return r
; /* network_drop_invalid_addresses() logs internally. */
303 network_drop_invalid_routes(network
);
304 r
= network_drop_invalid_nexthops(network
);
307 network_drop_invalid_bridge_fdb_entries(network
);
308 network_drop_invalid_bridge_mdb_entries(network
);
309 r
= network_drop_invalid_neighbors(network
);
312 network_drop_invalid_address_labels(network
);
313 network_drop_invalid_prefixes(network
);
314 network_drop_invalid_route_prefixes(network
);
315 network_drop_invalid_routing_policy_rules(network
);
316 network_drop_invalid_qdisc(network
);
317 network_drop_invalid_tclass(network
);
318 r
= sr_iov_drop_invalid_sections(UINT32_MAX
, network
->sr_iov_by_section
);
320 return r
; /* sr_iov_drop_invalid_sections() logs internally. */
321 network_drop_invalid_static_leases(network
);
326 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
327 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
328 _cleanup_(network_unrefp
) Network
*network
= NULL
;
329 const char *dropin_dirname
;
336 r
= null_or_empty_path(filename
);
338 return log_warning_errno(r
, "Failed to check if \"%s\" is empty: %m", filename
);
340 log_debug("Skipping empty file: %s", filename
);
344 fname
= strdup(filename
);
348 name
= strdup(basename(filename
));
352 d
= strrchr(name
, '.');
354 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
), "Invalid file name: %s", filename
);
358 dropin_dirname
= strjoina(name
, ".network.d");
360 network
= new(Network
, 1);
364 *network
= (Network
) {
365 .filename
= TAKE_PTR(fname
),
366 .name
= TAKE_PTR(name
),
371 .required_for_online
= -1,
372 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_INVALID
,
373 .activation_policy
= _ACTIVATION_POLICY_INVALID
,
380 .keep_configuration
= manager
->keep_configuration
,
382 .dhcp_duid
.type
= _DUID_TYPE_INVALID
,
384 .dhcp_use_ntp
= true,
385 .dhcp_routes_to_ntp
= true,
386 .dhcp_use_sip
= true,
387 .dhcp_use_captive_portal
= true,
388 .dhcp_use_dns
= true,
389 .dhcp_routes_to_dns
= true,
390 .dhcp_use_hostname
= true,
391 .dhcp_use_routes
= true,
392 .dhcp_use_gateway
= -1,
393 .dhcp_send_hostname
= true,
394 .dhcp_send_release
= true,
395 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
396 .dhcp_use_rapid_commit
= -1,
397 .dhcp_client_identifier
= _DHCP_CLIENT_ID_INVALID
,
398 .dhcp_route_table
= RT_TABLE_MAIN
,
399 .dhcp_ip_service_type
= -1,
400 .dhcp_broadcast
= -1,
401 .dhcp_ipv6_only_mode
= -1,
403 .dhcp6_use_address
= true,
404 .dhcp6_use_pd_prefix
= true,
405 .dhcp6_use_dns
= true,
406 .dhcp6_use_hostname
= true,
407 .dhcp6_use_ntp
= true,
408 .dhcp6_use_captive_portal
= true,
409 .dhcp6_use_rapid_commit
= true,
410 .dhcp6_send_hostname
= true,
411 .dhcp6_duid
.type
= _DUID_TYPE_INVALID
,
412 .dhcp6_client_start_mode
= _DHCP6_CLIENT_START_MODE_INVALID
,
413 .dhcp6_send_release
= true,
416 .dhcp_pd_announce
= true,
417 .dhcp_pd_assign
= true,
418 .dhcp_pd_manage_temporary_address
= true,
419 .dhcp_pd_subnet_id
= -1,
420 .dhcp_pd_route_metric
= DHCP6PD_ROUTE_METRIC
,
422 .dhcp_server_bind_to_interface
= true,
423 .dhcp_server_emit
[SD_DHCP_LEASE_DNS
].emit
= true,
424 .dhcp_server_emit
[SD_DHCP_LEASE_NTP
].emit
= true,
425 .dhcp_server_emit
[SD_DHCP_LEASE_SIP
].emit
= true,
426 .dhcp_server_emit_router
= true,
427 .dhcp_server_emit_timezone
= true,
428 .dhcp_server_rapid_commit
= true,
430 .router_lifetime_usec
= RADV_DEFAULT_ROUTER_LIFETIME_USEC
,
431 .router_dns_lifetime_usec
= RADV_DEFAULT_VALID_LIFETIME_USEC
,
432 .router_emit_dns
= true,
433 .router_emit_domains
= true,
439 .allow_port_to_be_root
= -1,
441 .multicast_flood
= -1,
442 .multicast_to_unicast
= -1,
443 .neighbor_suppression
= -1,
445 .bridge_proxy_arp
= -1,
446 .bridge_proxy_arp_wifi
= -1,
447 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
448 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
450 .bridge_vlan_pvid
= BRIDGE_VLAN_KEEP_PVID
,
452 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
453 .lldp_multicast_mode
= _SD_LLDP_MULTICAST_MODE_INVALID
,
455 .dns_default_route
= -1,
456 .llmnr
= RESOLVE_SUPPORT_YES
,
457 .mdns
= RESOLVE_SUPPORT_NO
,
458 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
459 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
461 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
462 .link_local
= _ADDRESS_FAMILY_INVALID
,
463 .ipv6ll_address_gen_mode
= _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID
,
465 .ip_forwarding
= { -1, -1, },
466 .ipv4_accept_local
= -1,
467 .ipv4_route_localnet
= -1,
468 .ipv6_privacy_extensions
= _IPV6_PRIVACY_EXTENSIONS_INVALID
,
469 .ipv6_dad_transmits
= -1,
470 .ipv6_proxy_ndp
= -1,
472 .proxy_arp_pvlan
= -1,
473 .ipv4_rp_filter
= _IP_REVERSE_PATH_FILTER_INVALID
,
476 .ndisc_use_dns
= true,
477 .ndisc_use_gateway
= true,
478 .ndisc_use_captive_portal
= true,
479 .ndisc_use_route_prefix
= true,
480 .ndisc_use_autonomous_prefix
= true,
481 .ndisc_use_onlink_prefix
= true,
482 .ndisc_use_mtu
= true,
483 .ndisc_use_hop_limit
= true,
484 .ndisc_use_reachable_time
= true,
485 .ndisc_use_retransmission_time
= true,
486 .ndisc_route_table
= RT_TABLE_MAIN
,
487 .ndisc_route_metric_high
= IPV6RA_ROUTE_METRIC_HIGH
,
488 .ndisc_route_metric_medium
= IPV6RA_ROUTE_METRIC_MEDIUM
,
489 .ndisc_route_metric_low
= IPV6RA_ROUTE_METRIC_LOW
,
490 .ndisc_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"
529 "TrafficControlQueueingDiscipline\0"
535 "DeficitRoundRobinScheduler\0"
536 "DeficitRoundRobinSchedulerClass\0"
537 "EnhancedTransmissionSelection\0"
539 "FairQueueingControlledDelay\0"
541 "GenericRandomEarlyDetection\0"
542 "HeavyHitterFilter\0"
543 "HierarchyTokenBucket\0"
544 "HierarchyTokenBucketClass\0"
550 "QuickFairQueueing\0"
551 "QuickFairQueueingClass\0"
552 "StochasticFairBlue\0"
553 "StochasticFairnessQueueing\0"
554 "TokenBucketFilter\0"
555 "TrivialLinkEqualizer\0",
556 config_item_perf_lookup
, network_network_gperf_lookup
,
559 &network
->stats_by_path
,
562 return r
; /* config_parse_many() logs internally. */
564 r
= network_add_ipv4ll_route(network
);
566 return log_warning_errno(r
, "%s: Failed to add IPv4LL route: %m", network
->filename
);
568 r
= network_add_default_route_on_device(network
);
570 return log_warning_errno(r
, "%s: Failed to add default route on device: %m",
573 r
= network_verify(network
);
575 return r
; /* network_verify() logs internally. */
577 r
= ordered_hashmap_ensure_put(networks
, &string_hash_ops
, network
->name
, network
);
579 return log_warning_errno(r
, "%s: Failed to store configuration into hashmap: %m", filename
);
585 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
586 _cleanup_strv_free_
char **files
= NULL
;
591 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
593 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
595 return log_error_errno(r
, "Failed to enumerate network files: %m");
597 STRV_FOREACH(f
, files
)
598 (void) network_load_one(manager
, networks
, *f
);
603 int network_reload(Manager
*manager
) {
604 OrderedHashmap
*new_networks
= NULL
;
610 r
= network_load(manager
, &new_networks
);
614 ORDERED_HASHMAP_FOREACH(n
, new_networks
) {
615 r
= network_get_by_name(manager
, n
->name
, &old
);
617 log_debug("Found new .network file: %s", n
->filename
);
621 if (!stats_by_path_equal(n
->stats_by_path
, old
->stats_by_path
)) {
622 log_debug("Found updated .network file: %s", n
->filename
);
626 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
634 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
635 manager
->networks
= new_networks
;
637 r
= manager_build_dhcp_pd_subnet_ids(manager
);
641 r
= manager_build_nexthop_ids(manager
);
648 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
653 int manager_build_dhcp_pd_subnet_ids(Manager
*manager
) {
659 set_clear(manager
->dhcp_pd_subnet_ids
);
661 ORDERED_HASHMAP_FOREACH(n
, manager
->networks
) {
668 if (n
->dhcp_pd_subnet_id
< 0)
671 r
= set_ensure_put(&manager
->dhcp_pd_subnet_ids
, &uint64_hash_ops
, &n
->dhcp_pd_subnet_id
);
679 static Network
*network_free(Network
*network
) {
684 free(network
->filename
);
685 free(network
->description
);
686 strv_free(network
->dropins
);
687 hashmap_free(network
->stats_by_path
);
690 net_match_clear(&network
->match
);
691 condition_free_list(network
->conditions
);
694 strv_free(network
->bind_carrier
);
697 strv_free(network
->ntp
);
700 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
701 in_addr_full_free(network
->dns
[i
]);
703 ordered_set_free(network
->search_domains
);
704 ordered_set_free(network
->route_domains
);
705 set_free_free(network
->dnssec_negative_trust_anchors
);
708 free(network
->dhcp_server_relay_agent_circuit_id
);
709 free(network
->dhcp_server_relay_agent_remote_id
);
710 free(network
->dhcp_server_boot_server_name
);
711 free(network
->dhcp_server_boot_filename
);
712 free(network
->dhcp_server_timezone
);
713 free(network
->dhcp_server_uplink_name
);
714 for (sd_dhcp_lease_server_type_t t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
715 free(network
->dhcp_server_emit
[t
].addresses
);
716 ordered_hashmap_free(network
->dhcp_server_send_options
);
717 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
720 free(network
->dhcp_vendor_class_identifier
);
721 free(network
->dhcp_mudurl
);
722 free(network
->dhcp_hostname
);
723 free(network
->dhcp_label
);
724 set_free(network
->dhcp_deny_listed_ip
);
725 set_free(network
->dhcp_allow_listed_ip
);
726 strv_free(network
->dhcp_user_class
);
727 set_free(network
->dhcp_request_options
);
728 ordered_hashmap_free(network
->dhcp_client_send_options
);
729 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
730 free(network
->dhcp_netlabel
);
731 nft_set_context_clear(&network
->dhcp_nft_set_context
);
734 free(network
->dhcp6_mudurl
);
735 free(network
->dhcp6_hostname
);
736 strv_free(network
->dhcp6_user_class
);
737 strv_free(network
->dhcp6_vendor_class
);
738 set_free(network
->dhcp6_request_options
);
739 ordered_hashmap_free(network
->dhcp6_client_send_options
);
740 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
741 free(network
->dhcp6_netlabel
);
742 nft_set_context_clear(&network
->dhcp6_nft_set_context
);
745 free(network
->dhcp_pd_uplink_name
);
746 set_free(network
->dhcp_pd_tokens
);
747 free(network
->dhcp_pd_netlabel
);
748 nft_set_context_clear(&network
->dhcp_pd_nft_set_context
);
750 /* Router advertisement */
751 ordered_set_free(network
->router_search_domains
);
752 free(network
->router_dns
);
753 free(network
->router_uplink_name
);
756 set_free(network
->ndisc_deny_listed_router
);
757 set_free(network
->ndisc_allow_listed_router
);
758 set_free(network
->ndisc_deny_listed_prefix
);
759 set_free(network
->ndisc_allow_listed_prefix
);
760 set_free(network
->ndisc_deny_listed_route_prefix
);
761 set_free(network
->ndisc_allow_listed_route_prefix
);
762 set_free(network
->ndisc_tokens
);
763 free(network
->ndisc_netlabel
);
764 nft_set_context_clear(&network
->ndisc_nft_set_context
);
767 free(network
->lldp_mudurl
);
770 free(network
->batadv_name
);
771 free(network
->bridge_name
);
772 free(network
->bond_name
);
773 free(network
->vrf_name
);
774 hashmap_free_free_key(network
->stacked_netdev_names
);
775 netdev_unref(network
->bridge
);
776 netdev_unref(network
->bond
);
777 netdev_unref(network
->vrf
);
778 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
781 set_free_free(network
->ipv6_proxy_ndp_addresses
);
782 ordered_hashmap_free(network
->addresses_by_section
);
783 hashmap_free(network
->routes_by_section
);
784 ordered_hashmap_free(network
->nexthops_by_section
);
785 hashmap_free_with_destructor(network
->bridge_fdb_entries_by_section
, bridge_fdb_free
);
786 hashmap_free_with_destructor(network
->bridge_mdb_entries_by_section
, bridge_mdb_free
);
787 ordered_hashmap_free(network
->neighbors_by_section
);
788 hashmap_free_with_destructor(network
->address_labels_by_section
, address_label_free
);
789 hashmap_free_with_destructor(network
->prefixes_by_section
, prefix_free
);
790 hashmap_free_with_destructor(network
->route_prefixes_by_section
, route_prefix_free
);
791 hashmap_free_with_destructor(network
->pref64_prefixes_by_section
, pref64_prefix_free
);
792 hashmap_free_with_destructor(network
->rules_by_section
, routing_policy_rule_free
);
793 hashmap_free_with_destructor(network
->dhcp_static_leases_by_section
, dhcp_static_lease_free
);
794 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
795 hashmap_free_with_destructor(network
->qdiscs_by_section
, qdisc_free
);
796 hashmap_free_with_destructor(network
->tclasses_by_section
, tclass_free
);
798 return mfree(network
);
801 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
803 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
810 network
= ordered_hashmap_get(manager
->networks
, name
);
819 bool network_has_static_ipv6_configurations(Network
*network
) {
828 ORDERED_HASHMAP_FOREACH(address
, network
->addresses_by_section
)
829 if (address
->family
== AF_INET6
)
832 HASHMAP_FOREACH(route
, network
->routes_by_section
)
833 if (route
->family
== AF_INET6
)
836 HASHMAP_FOREACH(fdb
, network
->bridge_fdb_entries_by_section
)
837 if (fdb
->family
== AF_INET6
)
840 HASHMAP_FOREACH(mdb
, network
->bridge_mdb_entries_by_section
)
841 if (mdb
->family
== AF_INET6
)
844 ORDERED_HASHMAP_FOREACH(neighbor
, network
->neighbors_by_section
)
845 if (neighbor
->family
== AF_INET6
)
848 if (!hashmap_isempty(network
->address_labels_by_section
))
851 if (!hashmap_isempty(network
->prefixes_by_section
))
854 if (!hashmap_isempty(network
->route_prefixes_by_section
))
857 if (!hashmap_isempty(network
->pref64_prefixes_by_section
))
863 int config_parse_stacked_netdev(
865 const char *filename
,
868 unsigned section_line
,
875 _cleanup_free_
char *name
= NULL
;
876 NetDevKind kind
= ltype
;
877 Hashmap
**h
= ASSERT_PTR(data
);
893 _NETDEV_KIND_TUNNEL
));
895 if (!ifname_valid(rvalue
)) {
896 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
897 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
901 name
= strdup(rvalue
);
905 r
= hashmap_ensure_put(h
, &string_hash_ops
, name
, INT_TO_PTR(kind
));
909 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
910 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
912 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
913 "NetDev '%s' specified twice, ignoring.", name
);
920 int config_parse_domains(
922 const char *filename
,
925 unsigned section_line
,
932 Network
*n
= ASSERT_PTR(userdata
);
939 if (isempty(rvalue
)) {
940 n
->search_domains
= ordered_set_free(n
->search_domains
);
941 n
->route_domains
= ordered_set_free(n
->route_domains
);
945 for (const char *p
= rvalue
;;) {
946 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
950 r
= extract_first_word(&p
, &w
, NULL
, 0);
954 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
955 "Failed to extract search or route domain, ignoring: %s", rvalue
);
961 is_route
= w
[0] == '~';
962 domain
= is_route
? w
+ 1 : w
;
964 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
965 /* If the root domain appears as is, or the special token "*" is found, we'll
966 * consider this as routing domain, unconditionally. */
968 domain
= "."; /* make sure we don't allow empty strings, thus write the root
971 r
= dns_name_normalize(domain
, 0, &normalized
);
973 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
974 "'%s' is not a valid domain name, ignoring.", domain
);
980 if (is_localhost(domain
)) {
981 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
982 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
988 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
989 r
= ordered_set_put_strdup(set
, domain
);
997 int config_parse_timezone(
999 const char *filename
,
1001 const char *section
,
1002 unsigned section_line
,
1009 char **tz
= ASSERT_PTR(data
);
1016 if (isempty(rvalue
)) {
1021 r
= verify_timezone(rvalue
, LOG_WARNING
);
1023 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1024 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1028 return free_and_strdup_warn(tz
, rvalue
);
1031 int config_parse_dns(
1033 const char *filename
,
1035 const char *section
,
1036 unsigned section_line
,
1043 Network
*n
= ASSERT_PTR(userdata
);
1050 if (isempty(rvalue
)) {
1051 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
1052 in_addr_full_free(n
->dns
[i
]);
1053 n
->dns
= mfree(n
->dns
);
1058 for (const char *p
= rvalue
;;) {
1059 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
1060 _cleanup_free_
char *w
= NULL
;
1061 struct in_addr_full
**m
;
1063 r
= extract_first_word(&p
, &w
, NULL
, 0);
1067 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1068 "Invalid syntax, ignoring: %s", rvalue
);
1074 r
= in_addr_full_new_from_string(w
, &dns
);
1076 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1077 "Failed to parse dns server address, ignoring: %s", w
);
1081 if (IN_SET(dns
->port
, 53, 853))
1084 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
1088 m
[n
->n_dns
++] = TAKE_PTR(dns
);
1093 int config_parse_dnssec_negative_trust_anchors(
1095 const char *filename
,
1097 const char *section
,
1098 unsigned section_line
,
1105 Set
**nta
= ASSERT_PTR(data
);
1112 if (isempty(rvalue
)) {
1113 *nta
= set_free_free(*nta
);
1117 for (const char *p
= rvalue
;;) {
1118 _cleanup_free_
char *w
= NULL
;
1120 r
= extract_first_word(&p
, &w
, NULL
, 0);
1124 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1125 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1131 r
= dns_name_is_valid(w
);
1133 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1134 "%s is not a valid domain name, ignoring.", w
);
1138 r
= set_ensure_consume(nta
, &dns_name_hash_ops
, TAKE_PTR(w
));
1144 int config_parse_ntp(
1146 const char *filename
,
1148 const char *section
,
1149 unsigned section_line
,
1156 char ***l
= ASSERT_PTR(data
);
1163 if (isempty(rvalue
)) {
1168 for (const char *p
= rvalue
;;) {
1169 _cleanup_free_
char *w
= NULL
;
1171 r
= extract_first_word(&p
, &w
, NULL
, 0);
1175 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1176 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1182 r
= dns_name_is_valid_or_address(w
);
1184 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1185 "%s is not a valid domain name or IP address, ignoring.", w
);
1189 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1190 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1191 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1192 MAX_NTP_SERVERS
, w
);
1196 r
= strv_consume(l
, TAKE_PTR(w
));
1202 int config_parse_required_for_online(
1204 const char *filename
,
1206 const char *section
,
1207 unsigned section_line
,
1214 Network
*network
= ASSERT_PTR(userdata
);
1221 if (isempty(rvalue
)) {
1222 network
->required_for_online
= -1;
1223 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_INVALID
;
1227 r
= parse_operational_state_range(rvalue
, &network
->required_operstate_for_online
);
1229 r
= parse_boolean(rvalue
);
1231 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1232 "Failed to parse %s= setting, ignoring assignment: %s",
1237 network
->required_for_online
= r
;
1238 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1242 network
->required_for_online
= true;
1246 int config_parse_link_group(
1248 const char *filename
,
1250 const char *section
,
1251 unsigned section_line
,
1258 Network
*network
= ASSERT_PTR(userdata
);
1266 if (isempty(rvalue
)) {
1267 network
->group
= -1;
1271 r
= safe_atoi32(rvalue
, &group
);
1273 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1274 "Failed to parse Group=, ignoring assignment: %s", rvalue
);
1279 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1280 "Value of Group= must be in the range 0…2147483647, ignoring assignment: %s", rvalue
);
1284 network
->group
= group
;
1288 int config_parse_ignore_carrier_loss(
1290 const char *filename
,
1292 const char *section
,
1293 unsigned section_line
,
1300 Network
*network
= ASSERT_PTR(userdata
);
1308 if (isempty(rvalue
)) {
1309 network
->ignore_carrier_loss_set
= false;
1313 r
= parse_boolean(rvalue
);
1315 network
->ignore_carrier_loss_set
= true;
1316 network
->ignore_carrier_loss_usec
= r
> 0 ? USEC_INFINITY
: 0;
1320 r
= parse_sec(rvalue
, &usec
);
1322 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1323 "Failed to parse %s=, ignoring assignment: %s", lvalue
, rvalue
);
1327 network
->ignore_carrier_loss_set
= true;
1328 network
->ignore_carrier_loss_usec
= usec
;
1332 DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online
, link_required_address_family
, AddressFamily
,
1333 "Failed to parse RequiredFamilyForOnline= setting");
1335 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1336 "Failed to parse KeepConfiguration= setting");
1338 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1339 [KEEP_CONFIGURATION_NO
] = "no",
1340 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1341 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1342 [KEEP_CONFIGURATION_STATIC
] = "static",
1343 [KEEP_CONFIGURATION_YES
] = "yes",
1346 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1348 static const char* const activation_policy_table
[_ACTIVATION_POLICY_MAX
] = {
1349 [ACTIVATION_POLICY_UP
] = "up",
1350 [ACTIVATION_POLICY_ALWAYS_UP
] = "always-up",
1351 [ACTIVATION_POLICY_MANUAL
] = "manual",
1352 [ACTIVATION_POLICY_ALWAYS_DOWN
] = "always-down",
1353 [ACTIVATION_POLICY_DOWN
] = "down",
1354 [ACTIVATION_POLICY_BOUND
] = "bound",
1357 DEFINE_STRING_TABLE_LOOKUP(activation_policy
, ActivationPolicy
);
1358 DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy
, activation_policy
, ActivationPolicy
, "Failed to parse activation policy");