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 /* 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
) /* Set implied default. */
278 network
->ignore_carrier_loss_usec
= network
->configure_without_carrier
? USEC_INFINITY
: 0;
280 if (IN_SET(network
->activation_policy
, ACTIVATION_POLICY_DOWN
, ACTIVATION_POLICY_ALWAYS_DOWN
, ACTIVATION_POLICY_MANUAL
)) {
281 if (network
->required_for_online
< 0 ||
282 (network
->required_for_online
== true && network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_DOWN
)) {
283 log_debug("%s: Setting RequiredForOnline=no because ActivationPolicy=%s.", network
->filename
,
284 activation_policy_to_string(network
->activation_policy
));
285 network
->required_for_online
= false;
286 } else if (network
->required_for_online
== true)
287 log_warning("%s: RequiredForOnline=yes and ActivationPolicy=%s, "
288 "this may cause a delay at boot.", network
->filename
,
289 activation_policy_to_string(network
->activation_policy
));
292 if (network
->required_for_online
< 0)
293 network
->required_for_online
= true;
295 if (network
->keep_configuration
< 0)
296 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
298 if (network
->ipv6_proxy_ndp
== 0 && !set_isempty(network
->ipv6_proxy_ndp_addresses
)) {
299 log_warning("%s: IPv6ProxyNDP= is disabled. Ignoring IPv6ProxyNDPAddress=.", network
->filename
);
300 network
->ipv6_proxy_ndp_addresses
= set_free_free(network
->ipv6_proxy_ndp_addresses
);
303 r
= network_drop_invalid_addresses(network
);
305 return r
; /* network_drop_invalid_addresses() logs internally. */
306 network_drop_invalid_routes(network
);
307 r
= 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_INVALID
,
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 .bridge_vlan_pvid
= BRIDGE_VLAN_KEEP_PVID
,
455 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
456 .lldp_multicast_mode
= _SD_LLDP_MULTICAST_MODE_INVALID
,
458 .dns_default_route
= -1,
459 .llmnr
= RESOLVE_SUPPORT_YES
,
460 .mdns
= RESOLVE_SUPPORT_NO
,
461 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
462 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
464 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
465 .link_local
= _ADDRESS_FAMILY_INVALID
,
466 .ipv6ll_address_gen_mode
= _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID
,
468 .ipv4_accept_local
= -1,
469 .ipv4_route_localnet
= -1,
470 .ipv6_privacy_extensions
= _IPV6_PRIVACY_EXTENSIONS_INVALID
,
471 .ipv6_dad_transmits
= -1,
472 .ipv6_proxy_ndp
= -1,
474 .proxy_arp_pvlan
= -1,
475 .ipv4_rp_filter
= _IP_REVERSE_PATH_FILTER_INVALID
,
477 .ipv6_accept_ra
= -1,
478 .ipv6_accept_ra_use_dns
= true,
479 .ipv6_accept_ra_use_gateway
= true,
480 .ipv6_accept_ra_use_captive_portal
= true,
481 .ipv6_accept_ra_use_route_prefix
= true,
482 .ipv6_accept_ra_use_autonomous_prefix
= true,
483 .ipv6_accept_ra_use_onlink_prefix
= true,
484 .ipv6_accept_ra_use_mtu
= true,
485 .ipv6_accept_ra_use_hop_limit
= true,
486 .ipv6_accept_ra_use_retransmission_time
= true,
487 .ipv6_accept_ra_use_icmp6_ratelimit
= true,
488 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
489 .ipv6_accept_ra_route_metric_high
= IPV6RA_ROUTE_METRIC_HIGH
,
490 .ipv6_accept_ra_route_metric_medium
= IPV6RA_ROUTE_METRIC_MEDIUM
,
491 .ipv6_accept_ra_route_metric_low
= IPV6RA_ROUTE_METRIC_LOW
,
492 .ipv6_accept_ra_start_dhcp6_client
= IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
,
494 .can_termination
= -1,
496 .ipoib_mode
= _IP_OVER_INFINIBAND_MODE_INVALID
,
500 r
= config_parse_many(
501 STRV_MAKE_CONST(filename
), NETWORK_DIRS
, dropin_dirname
, /* root = */ NULL
,
509 "RoutingPolicyRule\0"
512 "DHCP\0" /* compat */
515 "DHCPv6PrefixDelegation\0" /* compat */
516 "DHCPPrefixDelegation\0"
518 "DHCPServerStaticLease\0"
520 "IPv6NDPProxyAddress\0"
526 "IPv6PrefixDelegation\0"
531 "TrafficControlQueueingDiscipline\0"
537 "DeficitRoundRobinScheduler\0"
538 "DeficitRoundRobinSchedulerClass\0"
539 "EnhancedTransmissionSelection\0"
541 "FairQueueingControlledDelay\0"
543 "GenericRandomEarlyDetection\0"
544 "HeavyHitterFilter\0"
545 "HierarchyTokenBucket\0"
546 "HierarchyTokenBucketClass\0"
552 "QuickFairQueueing\0"
553 "QuickFairQueueingClass\0"
554 "StochasticFairBlue\0"
555 "StochasticFairnessQueueing\0"
556 "TokenBucketFilter\0"
557 "TrivialLinkEqualizer\0",
558 config_item_perf_lookup
, network_network_gperf_lookup
,
561 &network
->stats_by_path
,
564 return r
; /* config_parse_many() logs internally. */
566 r
= network_add_ipv4ll_route(network
);
568 return log_warning_errno(r
, "%s: Failed to add IPv4LL route: %m", network
->filename
);
570 r
= network_add_default_route_on_device(network
);
572 return log_warning_errno(r
, "%s: Failed to add default route on device: %m",
575 r
= network_verify(network
);
577 return r
; /* network_verify() logs internally. */
579 r
= ordered_hashmap_ensure_put(networks
, &string_hash_ops
, network
->name
, network
);
581 return log_warning_errno(r
, "%s: Failed to store configuration into hashmap: %m", filename
);
587 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
588 _cleanup_strv_free_
char **files
= NULL
;
593 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
595 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
597 return log_error_errno(r
, "Failed to enumerate network files: %m");
599 STRV_FOREACH(f
, files
)
600 (void) network_load_one(manager
, networks
, *f
);
605 int network_reload(Manager
*manager
) {
606 OrderedHashmap
*new_networks
= NULL
;
612 r
= network_load(manager
, &new_networks
);
616 ORDERED_HASHMAP_FOREACH(n
, new_networks
) {
617 r
= network_get_by_name(manager
, n
->name
, &old
);
619 log_debug("Found new .network file: %s", n
->filename
);
623 if (!stats_by_path_equal(n
->stats_by_path
, old
->stats_by_path
)) {
624 log_debug("Found updated .network file: %s", n
->filename
);
628 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
636 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
637 manager
->networks
= new_networks
;
639 r
= manager_build_dhcp_pd_subnet_ids(manager
);
643 r
= manager_build_nexthop_ids(manager
);
650 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
655 int manager_build_dhcp_pd_subnet_ids(Manager
*manager
) {
661 set_clear(manager
->dhcp_pd_subnet_ids
);
663 ORDERED_HASHMAP_FOREACH(n
, manager
->networks
) {
670 if (n
->dhcp_pd_subnet_id
< 0)
673 r
= set_ensure_put(&manager
->dhcp_pd_subnet_ids
, &uint64_hash_ops
, &n
->dhcp_pd_subnet_id
);
681 static Network
*network_free(Network
*network
) {
686 free(network
->filename
);
687 free(network
->description
);
688 strv_free(network
->dropins
);
689 hashmap_free(network
->stats_by_path
);
692 net_match_clear(&network
->match
);
693 condition_free_list(network
->conditions
);
696 strv_free(network
->bind_carrier
);
699 strv_free(network
->ntp
);
702 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
703 in_addr_full_free(network
->dns
[i
]);
705 ordered_set_free(network
->search_domains
);
706 ordered_set_free(network
->route_domains
);
707 set_free_free(network
->dnssec_negative_trust_anchors
);
710 free(network
->dhcp_server_relay_agent_circuit_id
);
711 free(network
->dhcp_server_relay_agent_remote_id
);
712 free(network
->dhcp_server_boot_server_name
);
713 free(network
->dhcp_server_boot_filename
);
714 free(network
->dhcp_server_timezone
);
715 free(network
->dhcp_server_uplink_name
);
716 for (sd_dhcp_lease_server_type_t t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
717 free(network
->dhcp_server_emit
[t
].addresses
);
718 ordered_hashmap_free(network
->dhcp_server_send_options
);
719 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
722 free(network
->dhcp_vendor_class_identifier
);
723 free(network
->dhcp_mudurl
);
724 free(network
->dhcp_hostname
);
725 free(network
->dhcp_label
);
726 set_free(network
->dhcp_deny_listed_ip
);
727 set_free(network
->dhcp_allow_listed_ip
);
728 strv_free(network
->dhcp_user_class
);
729 set_free(network
->dhcp_request_options
);
730 ordered_hashmap_free(network
->dhcp_client_send_options
);
731 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
732 free(network
->dhcp_netlabel
);
733 nft_set_context_clear(&network
->dhcp_nft_set_context
);
736 free(network
->dhcp6_mudurl
);
737 free(network
->dhcp6_hostname
);
738 strv_free(network
->dhcp6_user_class
);
739 strv_free(network
->dhcp6_vendor_class
);
740 set_free(network
->dhcp6_request_options
);
741 ordered_hashmap_free(network
->dhcp6_client_send_options
);
742 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
743 free(network
->dhcp6_netlabel
);
744 nft_set_context_clear(&network
->dhcp6_nft_set_context
);
747 free(network
->dhcp_pd_uplink_name
);
748 set_free(network
->dhcp_pd_tokens
);
749 free(network
->dhcp_pd_netlabel
);
750 nft_set_context_clear(&network
->dhcp_pd_nft_set_context
);
752 /* Router advertisement */
753 ordered_set_free(network
->router_search_domains
);
754 free(network
->router_dns
);
755 free(network
->router_uplink_name
);
758 set_free(network
->ndisc_deny_listed_router
);
759 set_free(network
->ndisc_allow_listed_router
);
760 set_free(network
->ndisc_deny_listed_prefix
);
761 set_free(network
->ndisc_allow_listed_prefix
);
762 set_free(network
->ndisc_deny_listed_route_prefix
);
763 set_free(network
->ndisc_allow_listed_route_prefix
);
764 set_free(network
->ndisc_tokens
);
765 free(network
->ndisc_netlabel
);
766 nft_set_context_clear(&network
->ndisc_nft_set_context
);
769 free(network
->lldp_mudurl
);
772 free(network
->batadv_name
);
773 free(network
->bridge_name
);
774 free(network
->bond_name
);
775 free(network
->vrf_name
);
776 hashmap_free_free_key(network
->stacked_netdev_names
);
777 netdev_unref(network
->bridge
);
778 netdev_unref(network
->bond
);
779 netdev_unref(network
->vrf
);
780 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
783 set_free_free(network
->ipv6_proxy_ndp_addresses
);
784 ordered_hashmap_free(network
->addresses_by_section
);
785 hashmap_free(network
->routes_by_section
);
786 ordered_hashmap_free(network
->nexthops_by_section
);
787 hashmap_free_with_destructor(network
->bridge_fdb_entries_by_section
, bridge_fdb_free
);
788 hashmap_free_with_destructor(network
->bridge_mdb_entries_by_section
, bridge_mdb_free
);
789 ordered_hashmap_free(network
->neighbors_by_section
);
790 hashmap_free_with_destructor(network
->address_labels_by_section
, address_label_free
);
791 hashmap_free_with_destructor(network
->prefixes_by_section
, prefix_free
);
792 hashmap_free_with_destructor(network
->route_prefixes_by_section
, route_prefix_free
);
793 hashmap_free_with_destructor(network
->pref64_prefixes_by_section
, pref64_prefix_free
);
794 hashmap_free_with_destructor(network
->rules_by_section
, routing_policy_rule_free
);
795 hashmap_free_with_destructor(network
->dhcp_static_leases_by_section
, dhcp_static_lease_free
);
796 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
797 hashmap_free_with_destructor(network
->qdiscs_by_section
, qdisc_free
);
798 hashmap_free_with_destructor(network
->tclasses_by_section
, tclass_free
);
800 return mfree(network
);
803 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
805 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
812 network
= ordered_hashmap_get(manager
->networks
, name
);
821 bool network_has_static_ipv6_configurations(Network
*network
) {
830 ORDERED_HASHMAP_FOREACH(address
, network
->addresses_by_section
)
831 if (address
->family
== AF_INET6
)
834 HASHMAP_FOREACH(route
, network
->routes_by_section
)
835 if (route
->family
== AF_INET6
)
838 HASHMAP_FOREACH(fdb
, network
->bridge_fdb_entries_by_section
)
839 if (fdb
->family
== AF_INET6
)
842 HASHMAP_FOREACH(mdb
, network
->bridge_mdb_entries_by_section
)
843 if (mdb
->family
== AF_INET6
)
846 ORDERED_HASHMAP_FOREACH(neighbor
, network
->neighbors_by_section
)
847 if (neighbor
->family
== AF_INET6
)
850 if (!hashmap_isempty(network
->address_labels_by_section
))
853 if (!hashmap_isempty(network
->prefixes_by_section
))
856 if (!hashmap_isempty(network
->route_prefixes_by_section
))
859 if (!hashmap_isempty(network
->pref64_prefixes_by_section
))
865 int config_parse_stacked_netdev(
867 const char *filename
,
870 unsigned section_line
,
877 _cleanup_free_
char *name
= NULL
;
878 NetDevKind kind
= ltype
;
879 Hashmap
**h
= ASSERT_PTR(data
);
895 _NETDEV_KIND_TUNNEL
));
897 if (!ifname_valid(rvalue
)) {
898 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
899 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
903 name
= strdup(rvalue
);
907 r
= hashmap_ensure_put(h
, &string_hash_ops
, name
, INT_TO_PTR(kind
));
911 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
912 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
914 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
915 "NetDev '%s' specified twice, ignoring.", name
);
922 int config_parse_domains(
924 const char *filename
,
927 unsigned section_line
,
934 Network
*n
= ASSERT_PTR(userdata
);
941 if (isempty(rvalue
)) {
942 n
->search_domains
= ordered_set_free(n
->search_domains
);
943 n
->route_domains
= ordered_set_free(n
->route_domains
);
947 for (const char *p
= rvalue
;;) {
948 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
952 r
= extract_first_word(&p
, &w
, NULL
, 0);
956 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
957 "Failed to extract search or route domain, ignoring: %s", rvalue
);
963 is_route
= w
[0] == '~';
964 domain
= is_route
? w
+ 1 : w
;
966 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
967 /* If the root domain appears as is, or the special token "*" is found, we'll
968 * consider this as routing domain, unconditionally. */
970 domain
= "."; /* make sure we don't allow empty strings, thus write the root
973 r
= dns_name_normalize(domain
, 0, &normalized
);
975 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
976 "'%s' is not a valid domain name, ignoring.", domain
);
982 if (is_localhost(domain
)) {
983 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
984 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
990 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
991 r
= ordered_set_put_strdup(set
, domain
);
999 int config_parse_timezone(
1001 const char *filename
,
1003 const char *section
,
1004 unsigned section_line
,
1011 char **tz
= ASSERT_PTR(data
);
1018 if (isempty(rvalue
)) {
1023 r
= verify_timezone(rvalue
, LOG_WARNING
);
1025 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1026 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1030 return free_and_strdup_warn(tz
, rvalue
);
1033 int config_parse_dns(
1035 const char *filename
,
1037 const char *section
,
1038 unsigned section_line
,
1045 Network
*n
= ASSERT_PTR(userdata
);
1052 if (isempty(rvalue
)) {
1053 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
1054 in_addr_full_free(n
->dns
[i
]);
1055 n
->dns
= mfree(n
->dns
);
1060 for (const char *p
= rvalue
;;) {
1061 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
1062 _cleanup_free_
char *w
= NULL
;
1063 struct in_addr_full
**m
;
1065 r
= extract_first_word(&p
, &w
, NULL
, 0);
1069 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1070 "Invalid syntax, ignoring: %s", rvalue
);
1076 r
= in_addr_full_new_from_string(w
, &dns
);
1078 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1079 "Failed to parse dns server address, ignoring: %s", w
);
1083 if (IN_SET(dns
->port
, 53, 853))
1086 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
1090 m
[n
->n_dns
++] = TAKE_PTR(dns
);
1095 int config_parse_dnssec_negative_trust_anchors(
1097 const char *filename
,
1099 const char *section
,
1100 unsigned section_line
,
1107 Set
**nta
= ASSERT_PTR(data
);
1114 if (isempty(rvalue
)) {
1115 *nta
= set_free_free(*nta
);
1119 for (const char *p
= rvalue
;;) {
1120 _cleanup_free_
char *w
= NULL
;
1122 r
= extract_first_word(&p
, &w
, NULL
, 0);
1126 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1127 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1133 r
= dns_name_is_valid(w
);
1135 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1136 "%s is not a valid domain name, ignoring.", w
);
1140 r
= set_ensure_consume(nta
, &dns_name_hash_ops
, TAKE_PTR(w
));
1146 int config_parse_ntp(
1148 const char *filename
,
1150 const char *section
,
1151 unsigned section_line
,
1158 char ***l
= ASSERT_PTR(data
);
1165 if (isempty(rvalue
)) {
1170 for (const char *p
= rvalue
;;) {
1171 _cleanup_free_
char *w
= NULL
;
1173 r
= extract_first_word(&p
, &w
, NULL
, 0);
1177 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1178 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1184 r
= dns_name_is_valid_or_address(w
);
1186 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1187 "%s is not a valid domain name or IP address, ignoring.", w
);
1191 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1192 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1193 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1194 MAX_NTP_SERVERS
, w
);
1198 r
= strv_consume(l
, TAKE_PTR(w
));
1204 int config_parse_required_for_online(
1206 const char *filename
,
1208 const char *section
,
1209 unsigned section_line
,
1216 Network
*network
= ASSERT_PTR(userdata
);
1223 if (isempty(rvalue
)) {
1224 network
->required_for_online
= -1;
1225 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_INVALID
;
1229 r
= parse_operational_state_range(rvalue
, &network
->required_operstate_for_online
);
1231 r
= parse_boolean(rvalue
);
1233 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1234 "Failed to parse %s= setting, ignoring assignment: %s",
1239 network
->required_for_online
= r
;
1240 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1244 network
->required_for_online
= true;
1248 int config_parse_link_group(
1250 const char *filename
,
1252 const char *section
,
1253 unsigned section_line
,
1260 Network
*network
= ASSERT_PTR(userdata
);
1268 if (isempty(rvalue
)) {
1269 network
->group
= -1;
1273 r
= safe_atoi32(rvalue
, &group
);
1275 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1276 "Failed to parse Group=, ignoring assignment: %s", rvalue
);
1281 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1282 "Value of Group= must be in the range 0…2147483647, ignoring assignment: %s", rvalue
);
1286 network
->group
= group
;
1290 int config_parse_ignore_carrier_loss(
1292 const char *filename
,
1294 const char *section
,
1295 unsigned section_line
,
1302 Network
*network
= ASSERT_PTR(userdata
);
1310 if (isempty(rvalue
)) {
1311 network
->ignore_carrier_loss_set
= false;
1315 r
= parse_boolean(rvalue
);
1317 network
->ignore_carrier_loss_set
= true;
1318 network
->ignore_carrier_loss_usec
= r
> 0 ? USEC_INFINITY
: 0;
1322 r
= parse_sec(rvalue
, &usec
);
1324 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1325 "Failed to parse %s=, ignoring assignment: %s", lvalue
, rvalue
);
1329 network
->ignore_carrier_loss_set
= true;
1330 network
->ignore_carrier_loss_usec
= usec
;
1334 DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online
, link_required_address_family
, AddressFamily
,
1335 "Failed to parse RequiredFamilyForOnline= setting");
1337 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1338 "Failed to parse KeepConfiguration= setting");
1340 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1341 [KEEP_CONFIGURATION_NO
] = "no",
1342 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1343 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1344 [KEEP_CONFIGURATION_STATIC
] = "static",
1345 [KEEP_CONFIGURATION_YES
] = "yes",
1348 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1350 static const char* const activation_policy_table
[_ACTIVATION_POLICY_MAX
] = {
1351 [ACTIVATION_POLICY_UP
] = "up",
1352 [ACTIVATION_POLICY_ALWAYS_UP
] = "always-up",
1353 [ACTIVATION_POLICY_MANUAL
] = "manual",
1354 [ACTIVATION_POLICY_ALWAYS_DOWN
] = "always-down",
1355 [ACTIVATION_POLICY_DOWN
] = "down",
1356 [ACTIVATION_POLICY_BOUND
] = "bound",
1359 DEFINE_STRING_TABLE_LOOKUP(activation_policy
, ActivationPolicy
);
1360 DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy
, activation_policy
, ActivationPolicy
, "Failed to parse activation policy");