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_with_destructor(network
->addresses_by_section
, address_free
);
191 network
->routes_by_section
= hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
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 /* IPMasquerade implies IPForward */
229 network
->ip_forward
|= network
->ip_masquerade
;
231 network_adjust_ipv6_proxy_ndp(network
);
232 network_adjust_ipv6_accept_ra(network
);
233 network_adjust_dhcp(network
);
234 network_adjust_radv(network
);
235 network_adjust_bridge_vlan(network
);
237 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
238 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
239 "Disabling UseMTU=.", network
->filename
);
240 network
->dhcp_use_mtu
= false;
243 if (network
->dhcp_critical
>= 0) {
244 if (network
->keep_configuration
>= 0) {
245 if (network
->manager
->keep_configuration
< 0)
246 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
247 "Ignoring CriticalConnection=.", network
->filename
);
248 } else if (network
->dhcp_critical
)
249 /* CriticalConnection=yes also preserve foreign static configurations. */
250 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
252 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
255 if (!strv_isempty(network
->bind_carrier
)) {
256 if (!IN_SET(network
->activation_policy
, _ACTIVATION_POLICY_INVALID
, ACTIVATION_POLICY_BOUND
))
257 log_warning("%s: ActivationPolicy=bound is required with BindCarrier=. "
258 "Setting ActivationPolicy=bound.", network
->filename
);
259 network
->activation_policy
= ACTIVATION_POLICY_BOUND
;
260 } else if (network
->activation_policy
== ACTIVATION_POLICY_BOUND
) {
261 log_warning("%s: ActivationPolicy=bound requires BindCarrier=. "
262 "Ignoring ActivationPolicy=bound.", network
->filename
);
263 network
->activation_policy
= ACTIVATION_POLICY_UP
;
266 if (network
->activation_policy
== _ACTIVATION_POLICY_INVALID
)
267 network
->activation_policy
= ACTIVATION_POLICY_UP
;
269 if (network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_UP
) {
270 if (network
->ignore_carrier_loss_set
&& network
->ignore_carrier_loss_usec
< USEC_INFINITY
)
271 log_warning("%s: IgnoreCarrierLoss=no or finite timespan conflicts with ActivationPolicy=always-up. "
272 "Setting IgnoreCarrierLoss=yes.", network
->filename
);
273 network
->ignore_carrier_loss_set
= true;
274 network
->ignore_carrier_loss_usec
= USEC_INFINITY
;
277 if (!network
->ignore_carrier_loss_set
) {
278 network
->ignore_carrier_loss_set
= true;
279 network
->ignore_carrier_loss_usec
= network
->configure_without_carrier
? USEC_INFINITY
: 0;
282 if (IN_SET(network
->activation_policy
, ACTIVATION_POLICY_DOWN
, ACTIVATION_POLICY_ALWAYS_DOWN
, ACTIVATION_POLICY_MANUAL
)) {
283 if (network
->required_for_online
< 0 ||
284 (network
->required_for_online
== true && network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_DOWN
)) {
285 log_debug("%s: Setting RequiredForOnline=no because ActivationPolicy=%s.", network
->filename
,
286 activation_policy_to_string(network
->activation_policy
));
287 network
->required_for_online
= false;
288 } else if (network
->required_for_online
== true)
289 log_warning("%s: RequiredForOnline=yes and ActivationPolicy=%s, "
290 "this may cause a delay at boot.", network
->filename
,
291 activation_policy_to_string(network
->activation_policy
));
294 if (network
->required_for_online
< 0)
295 network
->required_for_online
= true;
297 if (network
->keep_configuration
< 0)
298 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
300 if (network
->ipv6_proxy_ndp
== 0 && !set_isempty(network
->ipv6_proxy_ndp_addresses
)) {
301 log_warning("%s: IPv6ProxyNDP= is disabled. Ignoring IPv6ProxyNDPAddress=.", network
->filename
);
302 network
->ipv6_proxy_ndp_addresses
= set_free_free(network
->ipv6_proxy_ndp_addresses
);
305 r
= network_drop_invalid_addresses(network
);
307 return r
; /* network_drop_invalid_addresses() logs internally. */
308 network_drop_invalid_routes(network
);
309 network_drop_invalid_nexthops(network
);
310 network_drop_invalid_bridge_fdb_entries(network
);
311 network_drop_invalid_bridge_mdb_entries(network
);
312 r
= network_drop_invalid_neighbors(network
);
315 network_drop_invalid_address_labels(network
);
316 network_drop_invalid_prefixes(network
);
317 network_drop_invalid_route_prefixes(network
);
318 network_drop_invalid_routing_policy_rules(network
);
319 network_drop_invalid_qdisc(network
);
320 network_drop_invalid_tclass(network
);
321 r
= sr_iov_drop_invalid_sections(UINT32_MAX
, network
->sr_iov_by_section
);
323 return r
; /* sr_iov_drop_invalid_sections() logs internally. */
324 network_drop_invalid_static_leases(network
);
329 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
330 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
331 _cleanup_(network_unrefp
) Network
*network
= NULL
;
332 const char *dropin_dirname
;
339 r
= null_or_empty_path(filename
);
341 return log_warning_errno(r
, "Failed to check if \"%s\" is empty: %m", filename
);
343 log_debug("Skipping empty file: %s", filename
);
347 fname
= strdup(filename
);
351 name
= strdup(basename(filename
));
355 d
= strrchr(name
, '.');
357 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
), "Invalid file name: %s", filename
);
361 dropin_dirname
= strjoina(name
, ".network.d");
363 network
= new(Network
, 1);
367 *network
= (Network
) {
368 .filename
= TAKE_PTR(fname
),
369 .name
= TAKE_PTR(name
),
374 .required_for_online
= -1,
375 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
376 .activation_policy
= _ACTIVATION_POLICY_INVALID
,
383 .keep_configuration
= manager
->keep_configuration
,
385 .dhcp_duid
.type
= _DUID_TYPE_INVALID
,
387 .dhcp_use_ntp
= true,
388 .dhcp_routes_to_ntp
= true,
389 .dhcp_use_sip
= true,
390 .dhcp_use_captive_portal
= true,
391 .dhcp_use_dns
= true,
392 .dhcp_routes_to_dns
= true,
393 .dhcp_use_hostname
= true,
394 .dhcp_use_routes
= true,
395 .dhcp_use_gateway
= -1,
396 .dhcp_send_hostname
= true,
397 .dhcp_send_release
= true,
398 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
399 .dhcp_use_rapid_commit
= -1,
400 .dhcp_client_identifier
= _DHCP_CLIENT_ID_INVALID
,
401 .dhcp_route_table
= RT_TABLE_MAIN
,
402 .dhcp_ip_service_type
= -1,
403 .dhcp_broadcast
= -1,
404 .dhcp_ipv6_only_mode
= -1,
406 .dhcp6_use_address
= true,
407 .dhcp6_use_pd_prefix
= true,
408 .dhcp6_use_dns
= true,
409 .dhcp6_use_hostname
= true,
410 .dhcp6_use_ntp
= true,
411 .dhcp6_use_captive_portal
= true,
412 .dhcp6_use_rapid_commit
= true,
413 .dhcp6_send_hostname
= true,
414 .dhcp6_duid
.type
= _DUID_TYPE_INVALID
,
415 .dhcp6_client_start_mode
= _DHCP6_CLIENT_START_MODE_INVALID
,
416 .dhcp6_send_release
= true,
419 .dhcp_pd_announce
= true,
420 .dhcp_pd_assign
= true,
421 .dhcp_pd_manage_temporary_address
= true,
422 .dhcp_pd_subnet_id
= -1,
423 .dhcp_pd_route_metric
= DHCP6PD_ROUTE_METRIC
,
425 .dhcp_server_bind_to_interface
= true,
426 .dhcp_server_emit
[SD_DHCP_LEASE_DNS
].emit
= true,
427 .dhcp_server_emit
[SD_DHCP_LEASE_NTP
].emit
= true,
428 .dhcp_server_emit
[SD_DHCP_LEASE_SIP
].emit
= true,
429 .dhcp_server_emit_router
= true,
430 .dhcp_server_emit_timezone
= true,
431 .dhcp_server_rapid_commit
= true,
433 .router_lifetime_usec
= RADV_DEFAULT_ROUTER_LIFETIME_USEC
,
434 .router_dns_lifetime_usec
= RADV_DEFAULT_VALID_LIFETIME_USEC
,
435 .router_emit_dns
= true,
436 .router_emit_domains
= true,
442 .allow_port_to_be_root
= -1,
444 .multicast_flood
= -1,
445 .multicast_to_unicast
= -1,
446 .neighbor_suppression
= -1,
448 .bridge_proxy_arp
= -1,
449 .bridge_proxy_arp_wifi
= -1,
450 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
451 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
453 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
454 .lldp_multicast_mode
= _SD_LLDP_MULTICAST_MODE_INVALID
,
456 .dns_default_route
= -1,
457 .llmnr
= RESOLVE_SUPPORT_YES
,
458 .mdns
= RESOLVE_SUPPORT_NO
,
459 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
460 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
462 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
463 .link_local
= _ADDRESS_FAMILY_INVALID
,
464 .ipv6ll_address_gen_mode
= _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID
,
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 .ipv4_rp_filter
= _IP_REVERSE_PATH_FILTER_INVALID
,
474 .ipv6_accept_ra
= -1,
475 .ipv6_accept_ra_use_dns
= true,
476 .ipv6_accept_ra_use_gateway
= true,
477 .ipv6_accept_ra_use_captive_portal
= true,
478 .ipv6_accept_ra_use_route_prefix
= true,
479 .ipv6_accept_ra_use_autonomous_prefix
= true,
480 .ipv6_accept_ra_use_onlink_prefix
= true,
481 .ipv6_accept_ra_use_mtu
= true,
482 .ipv6_accept_ra_use_hop_limit
= true,
483 .ipv6_accept_ra_use_icmp6_ratelimit
= true,
484 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
485 .ipv6_accept_ra_route_metric_high
= IPV6RA_ROUTE_METRIC_HIGH
,
486 .ipv6_accept_ra_route_metric_medium
= IPV6RA_ROUTE_METRIC_MEDIUM
,
487 .ipv6_accept_ra_route_metric_low
= IPV6RA_ROUTE_METRIC_LOW
,
488 .ipv6_accept_ra_start_dhcp6_client
= IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
,
490 .can_termination
= -1,
492 .ipoib_mode
= _IP_OVER_INFINIBAND_MODE_INVALID
,
496 r
= config_parse_many(
497 STRV_MAKE_CONST(filename
), NETWORK_DIRS
, dropin_dirname
, /* root = */ NULL
,
505 "RoutingPolicyRule\0"
508 "DHCP\0" /* compat */
511 "DHCPv6PrefixDelegation\0" /* compat */
512 "DHCPPrefixDelegation\0"
514 "DHCPServerStaticLease\0"
516 "IPv6NDPProxyAddress\0"
522 "IPv6PrefixDelegation\0"
527 "TrafficControlQueueingDiscipline\0"
533 "DeficitRoundRobinScheduler\0"
534 "DeficitRoundRobinSchedulerClass\0"
535 "EnhancedTransmissionSelection\0"
537 "FairQueueingControlledDelay\0"
539 "GenericRandomEarlyDetection\0"
540 "HeavyHitterFilter\0"
541 "HierarchyTokenBucket\0"
542 "HierarchyTokenBucketClass\0"
548 "QuickFairQueueing\0"
549 "QuickFairQueueingClass\0"
550 "StochasticFairBlue\0"
551 "StochasticFairnessQueueing\0"
552 "TokenBucketFilter\0"
553 "TrivialLinkEqualizer\0",
554 config_item_perf_lookup
, network_network_gperf_lookup
,
557 &network
->stats_by_path
,
560 return r
; /* config_parse_many() logs internally. */
562 r
= network_add_ipv4ll_route(network
);
564 return log_warning_errno(r
, "%s: Failed to add IPv4LL route: %m", network
->filename
);
566 r
= network_add_default_route_on_device(network
);
568 return log_warning_errno(r
, "%s: Failed to add default route on device: %m",
571 r
= network_verify(network
);
573 return r
; /* network_verify() logs internally. */
575 r
= ordered_hashmap_ensure_put(networks
, &string_hash_ops
, network
->name
, network
);
577 return log_warning_errno(r
, "%s: Failed to store configuration into hashmap: %m", filename
);
583 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
584 _cleanup_strv_free_
char **files
= NULL
;
589 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
591 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
593 return log_error_errno(r
, "Failed to enumerate network files: %m");
595 STRV_FOREACH(f
, files
)
596 (void) network_load_one(manager
, networks
, *f
);
601 int network_reload(Manager
*manager
) {
602 OrderedHashmap
*new_networks
= NULL
;
608 r
= network_load(manager
, &new_networks
);
612 ORDERED_HASHMAP_FOREACH(n
, new_networks
) {
613 r
= network_get_by_name(manager
, n
->name
, &old
);
615 log_debug("Found new .network file: %s", n
->filename
);
619 if (!stats_by_path_equal(n
->stats_by_path
, old
->stats_by_path
)) {
620 log_debug("Found updated .network file: %s", n
->filename
);
624 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
632 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
633 manager
->networks
= new_networks
;
635 return manager_build_dhcp_pd_subnet_ids(manager
);
638 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
643 int manager_build_dhcp_pd_subnet_ids(Manager
*manager
) {
649 set_clear(manager
->dhcp_pd_subnet_ids
);
651 ORDERED_HASHMAP_FOREACH(n
, manager
->networks
) {
658 if (n
->dhcp_pd_subnet_id
< 0)
661 r
= set_ensure_put(&manager
->dhcp_pd_subnet_ids
, &uint64_hash_ops
, &n
->dhcp_pd_subnet_id
);
669 static Network
*network_free(Network
*network
) {
674 free(network
->filename
);
675 free(network
->description
);
676 strv_free(network
->dropins
);
677 hashmap_free(network
->stats_by_path
);
680 net_match_clear(&network
->match
);
681 condition_free_list(network
->conditions
);
684 strv_free(network
->bind_carrier
);
687 strv_free(network
->ntp
);
690 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
691 in_addr_full_free(network
->dns
[i
]);
693 ordered_set_free(network
->search_domains
);
694 ordered_set_free(network
->route_domains
);
695 set_free_free(network
->dnssec_negative_trust_anchors
);
698 free(network
->dhcp_server_relay_agent_circuit_id
);
699 free(network
->dhcp_server_relay_agent_remote_id
);
700 free(network
->dhcp_server_boot_server_name
);
701 free(network
->dhcp_server_boot_filename
);
702 free(network
->dhcp_server_timezone
);
703 free(network
->dhcp_server_uplink_name
);
704 for (sd_dhcp_lease_server_type_t t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
705 free(network
->dhcp_server_emit
[t
].addresses
);
706 ordered_hashmap_free(network
->dhcp_server_send_options
);
707 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
710 free(network
->dhcp_vendor_class_identifier
);
711 free(network
->dhcp_mudurl
);
712 free(network
->dhcp_hostname
);
713 free(network
->dhcp_label
);
714 set_free(network
->dhcp_deny_listed_ip
);
715 set_free(network
->dhcp_allow_listed_ip
);
716 strv_free(network
->dhcp_user_class
);
717 set_free(network
->dhcp_request_options
);
718 ordered_hashmap_free(network
->dhcp_client_send_options
);
719 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
720 free(network
->dhcp_netlabel
);
721 nft_set_context_clear(&network
->dhcp_nft_set_context
);
724 free(network
->dhcp6_mudurl
);
725 free(network
->dhcp6_hostname
);
726 strv_free(network
->dhcp6_user_class
);
727 strv_free(network
->dhcp6_vendor_class
);
728 set_free(network
->dhcp6_request_options
);
729 ordered_hashmap_free(network
->dhcp6_client_send_options
);
730 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
731 free(network
->dhcp6_netlabel
);
732 nft_set_context_clear(&network
->dhcp6_nft_set_context
);
735 free(network
->dhcp_pd_uplink_name
);
736 set_free(network
->dhcp_pd_tokens
);
737 free(network
->dhcp_pd_netlabel
);
738 nft_set_context_clear(&network
->dhcp_pd_nft_set_context
);
740 /* Router advertisement */
741 ordered_set_free(network
->router_search_domains
);
742 free(network
->router_dns
);
743 free(network
->router_uplink_name
);
746 set_free(network
->ndisc_deny_listed_router
);
747 set_free(network
->ndisc_allow_listed_router
);
748 set_free(network
->ndisc_deny_listed_prefix
);
749 set_free(network
->ndisc_allow_listed_prefix
);
750 set_free(network
->ndisc_deny_listed_route_prefix
);
751 set_free(network
->ndisc_allow_listed_route_prefix
);
752 set_free(network
->ndisc_tokens
);
753 free(network
->ndisc_netlabel
);
754 nft_set_context_clear(&network
->ndisc_nft_set_context
);
757 free(network
->lldp_mudurl
);
760 free(network
->batadv_name
);
761 free(network
->bridge_name
);
762 free(network
->bond_name
);
763 free(network
->vrf_name
);
764 hashmap_free_free_key(network
->stacked_netdev_names
);
765 netdev_unref(network
->bridge
);
766 netdev_unref(network
->bond
);
767 netdev_unref(network
->vrf
);
768 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
771 set_free_free(network
->ipv6_proxy_ndp_addresses
);
772 ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
773 hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
774 hashmap_free_with_destructor(network
->nexthops_by_section
, nexthop_free
);
775 hashmap_free_with_destructor(network
->bridge_fdb_entries_by_section
, bridge_fdb_free
);
776 hashmap_free_with_destructor(network
->bridge_mdb_entries_by_section
, bridge_mdb_free
);
777 ordered_hashmap_free_with_destructor(network
->neighbors_by_section
, neighbor_free
);
778 hashmap_free_with_destructor(network
->address_labels_by_section
, address_label_free
);
779 hashmap_free_with_destructor(network
->prefixes_by_section
, prefix_free
);
780 hashmap_free_with_destructor(network
->route_prefixes_by_section
, route_prefix_free
);
781 hashmap_free_with_destructor(network
->pref64_prefixes_by_section
, pref64_prefix_free
);
782 hashmap_free_with_destructor(network
->rules_by_section
, routing_policy_rule_free
);
783 hashmap_free_with_destructor(network
->dhcp_static_leases_by_section
, dhcp_static_lease_free
);
784 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
785 hashmap_free_with_destructor(network
->qdiscs_by_section
, qdisc_free
);
786 hashmap_free_with_destructor(network
->tclasses_by_section
, tclass_free
);
788 return mfree(network
);
791 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
793 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
800 network
= ordered_hashmap_get(manager
->networks
, name
);
809 bool network_has_static_ipv6_configurations(Network
*network
) {
818 ORDERED_HASHMAP_FOREACH(address
, network
->addresses_by_section
)
819 if (address
->family
== AF_INET6
)
822 HASHMAP_FOREACH(route
, network
->routes_by_section
)
823 if (route
->family
== AF_INET6
)
826 HASHMAP_FOREACH(fdb
, network
->bridge_fdb_entries_by_section
)
827 if (fdb
->family
== AF_INET6
)
830 HASHMAP_FOREACH(mdb
, network
->bridge_mdb_entries_by_section
)
831 if (mdb
->family
== AF_INET6
)
834 ORDERED_HASHMAP_FOREACH(neighbor
, network
->neighbors_by_section
)
835 if (neighbor
->family
== AF_INET6
)
838 if (!hashmap_isempty(network
->address_labels_by_section
))
841 if (!hashmap_isempty(network
->prefixes_by_section
))
844 if (!hashmap_isempty(network
->route_prefixes_by_section
))
847 if (!hashmap_isempty(network
->pref64_prefixes_by_section
))
853 int config_parse_stacked_netdev(
855 const char *filename
,
858 unsigned section_line
,
865 _cleanup_free_
char *name
= NULL
;
866 NetDevKind kind
= ltype
;
867 Hashmap
**h
= ASSERT_PTR(data
);
883 _NETDEV_KIND_TUNNEL
));
885 if (!ifname_valid(rvalue
)) {
886 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
887 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
891 name
= strdup(rvalue
);
895 r
= hashmap_ensure_put(h
, &string_hash_ops
, name
, INT_TO_PTR(kind
));
899 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
900 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
902 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
903 "NetDev '%s' specified twice, ignoring.", name
);
910 int config_parse_domains(
912 const char *filename
,
915 unsigned section_line
,
922 Network
*n
= ASSERT_PTR(userdata
);
929 if (isempty(rvalue
)) {
930 n
->search_domains
= ordered_set_free(n
->search_domains
);
931 n
->route_domains
= ordered_set_free(n
->route_domains
);
935 for (const char *p
= rvalue
;;) {
936 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
940 r
= extract_first_word(&p
, &w
, NULL
, 0);
944 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
945 "Failed to extract search or route domain, ignoring: %s", rvalue
);
951 is_route
= w
[0] == '~';
952 domain
= is_route
? w
+ 1 : w
;
954 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
955 /* If the root domain appears as is, or the special token "*" is found, we'll
956 * consider this as routing domain, unconditionally. */
958 domain
= "."; /* make sure we don't allow empty strings, thus write the root
961 r
= dns_name_normalize(domain
, 0, &normalized
);
963 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
964 "'%s' is not a valid domain name, ignoring.", domain
);
970 if (is_localhost(domain
)) {
971 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
972 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
978 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
979 r
= ordered_set_put_strdup(set
, domain
);
987 int config_parse_timezone(
989 const char *filename
,
992 unsigned section_line
,
999 char **tz
= ASSERT_PTR(data
);
1006 if (isempty(rvalue
)) {
1011 r
= verify_timezone(rvalue
, LOG_WARNING
);
1013 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1014 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1018 return free_and_strdup_warn(tz
, rvalue
);
1021 int config_parse_dns(
1023 const char *filename
,
1025 const char *section
,
1026 unsigned section_line
,
1033 Network
*n
= ASSERT_PTR(userdata
);
1040 if (isempty(rvalue
)) {
1041 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
1042 in_addr_full_free(n
->dns
[i
]);
1043 n
->dns
= mfree(n
->dns
);
1048 for (const char *p
= rvalue
;;) {
1049 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
1050 _cleanup_free_
char *w
= NULL
;
1051 struct in_addr_full
**m
;
1053 r
= extract_first_word(&p
, &w
, NULL
, 0);
1057 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1058 "Invalid syntax, ignoring: %s", rvalue
);
1064 r
= in_addr_full_new_from_string(w
, &dns
);
1066 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1067 "Failed to parse dns server address, ignoring: %s", w
);
1071 if (IN_SET(dns
->port
, 53, 853))
1074 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
1078 m
[n
->n_dns
++] = TAKE_PTR(dns
);
1083 int config_parse_dnssec_negative_trust_anchors(
1085 const char *filename
,
1087 const char *section
,
1088 unsigned section_line
,
1095 Set
**nta
= ASSERT_PTR(data
);
1102 if (isempty(rvalue
)) {
1103 *nta
= set_free_free(*nta
);
1107 for (const char *p
= rvalue
;;) {
1108 _cleanup_free_
char *w
= NULL
;
1110 r
= extract_first_word(&p
, &w
, NULL
, 0);
1114 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1115 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1121 r
= dns_name_is_valid(w
);
1123 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1124 "%s is not a valid domain name, ignoring.", w
);
1128 r
= set_ensure_consume(nta
, &dns_name_hash_ops
, TAKE_PTR(w
));
1134 int config_parse_ntp(
1136 const char *filename
,
1138 const char *section
,
1139 unsigned section_line
,
1146 char ***l
= ASSERT_PTR(data
);
1153 if (isempty(rvalue
)) {
1158 for (const char *p
= rvalue
;;) {
1159 _cleanup_free_
char *w
= NULL
;
1161 r
= extract_first_word(&p
, &w
, NULL
, 0);
1165 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1166 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1172 r
= dns_name_is_valid_or_address(w
);
1174 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1175 "%s is not a valid domain name or IP address, ignoring.", w
);
1179 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1180 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1181 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1182 MAX_NTP_SERVERS
, w
);
1186 r
= strv_consume(l
, TAKE_PTR(w
));
1192 int config_parse_required_for_online(
1194 const char *filename
,
1196 const char *section
,
1197 unsigned section_line
,
1204 Network
*network
= ASSERT_PTR(userdata
);
1205 LinkOperationalStateRange range
;
1206 bool required
= true;
1213 if (isempty(rvalue
)) {
1214 network
->required_for_online
= -1;
1215 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1219 r
= parse_operational_state_range(rvalue
, &range
);
1221 r
= parse_boolean(rvalue
);
1223 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1224 "Failed to parse %s= setting, ignoring assignment: %s",
1230 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1233 network
->required_for_online
= required
;
1234 network
->required_operstate_for_online
= range
;
1239 int config_parse_link_group(
1241 const char *filename
,
1243 const char *section
,
1244 unsigned section_line
,
1251 Network
*network
= ASSERT_PTR(userdata
);
1259 if (isempty(rvalue
)) {
1260 network
->group
= -1;
1264 r
= safe_atoi32(rvalue
, &group
);
1266 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1267 "Failed to parse Group=, ignoring assignment: %s", rvalue
);
1272 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1273 "Value of Group= must be in the range 0…2147483647, ignoring assignment: %s", rvalue
);
1277 network
->group
= group
;
1281 int config_parse_ignore_carrier_loss(
1283 const char *filename
,
1285 const char *section
,
1286 unsigned section_line
,
1293 Network
*network
= ASSERT_PTR(userdata
);
1301 if (isempty(rvalue
)) {
1302 network
->ignore_carrier_loss_set
= false;
1306 r
= parse_boolean(rvalue
);
1308 network
->ignore_carrier_loss_set
= true;
1309 network
->ignore_carrier_loss_usec
= r
> 0 ? USEC_INFINITY
: 0;
1313 r
= parse_sec(rvalue
, &usec
);
1315 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1316 "Failed to parse %s=, ignoring assignment: %s", lvalue
, rvalue
);
1320 network
->ignore_carrier_loss_set
= true;
1321 network
->ignore_carrier_loss_usec
= usec
;
1325 DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online
, link_required_address_family
, AddressFamily
,
1326 "Failed to parse RequiredFamilyForOnline= setting");
1328 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1329 "Failed to parse KeepConfiguration= setting");
1331 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1332 [KEEP_CONFIGURATION_NO
] = "no",
1333 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1334 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1335 [KEEP_CONFIGURATION_STATIC
] = "static",
1336 [KEEP_CONFIGURATION_YES
] = "yes",
1339 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1341 static const char* const activation_policy_table
[_ACTIVATION_POLICY_MAX
] = {
1342 [ACTIVATION_POLICY_UP
] = "up",
1343 [ACTIVATION_POLICY_ALWAYS_UP
] = "always-up",
1344 [ACTIVATION_POLICY_MANUAL
] = "manual",
1345 [ACTIVATION_POLICY_ALWAYS_DOWN
] = "always-down",
1346 [ACTIVATION_POLICY_DOWN
] = "down",
1347 [ACTIVATION_POLICY_BOUND
] = "bound",
1350 DEFINE_STRING_TABLE_LOOKUP(activation_policy
, ActivationPolicy
);
1351 DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy
, activation_policy
, ActivationPolicy
, "Failed to parse activation policy");