1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 /* Make sure the net/if.h header is included before any linux/ one */
5 #include <netinet/in.h>
6 #include <linux/netdevice.h>
9 #include "alloc-util.h"
10 #include "conf-files.h"
11 #include "conf-parser.h"
12 #include "dns-domain.h"
14 #include "hostname-util.h"
15 #include "in-addr-util.h"
16 #include "net-condition.h"
17 #include "netdev/macvlan.h"
18 #include "networkd-address-label.h"
19 #include "networkd-address.h"
20 #include "networkd-bridge-fdb.h"
21 #include "networkd-bridge-mdb.h"
22 #include "networkd-dhcp-common.h"
23 #include "networkd-dhcp-server-static-lease.h"
24 #include "networkd-ipv6-proxy-ndp.h"
25 #include "networkd-manager.h"
26 #include "networkd-ndisc.h"
27 #include "networkd-neighbor.h"
28 #include "networkd-network.h"
29 #include "networkd-nexthop.h"
30 #include "networkd-radv.h"
31 #include "networkd-route.h"
32 #include "networkd-routing-policy-rule.h"
33 #include "networkd-sriov.h"
34 #include "parse-util.h"
35 #include "path-lookup.h"
37 #include "radv-internal.h"
39 #include "socket-util.h"
40 #include "stat-util.h"
41 #include "string-table.h"
42 #include "string-util.h"
46 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret
) {
47 const char *kind_string
;
51 /* For test-networkd-conf, the check must be earlier than the assertions. */
56 assert(network
->manager
);
57 assert(network
->filename
);
60 if (kind
== _NETDEV_KIND_TUNNEL
)
61 kind_string
= "tunnel";
63 kind_string
= netdev_kind_to_string(kind
);
65 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
66 "%s: Invalid NetDev kind of %s, ignoring assignment.",
67 network
->filename
, name
);
70 r
= netdev_get(network
->manager
, name
, &netdev
);
72 return log_warning_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
73 network
->filename
, name
);
75 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
81 NETDEV_KIND_IP6GRETAP
,
87 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
88 "%s: NetDev %s is not a %s, ignoring assignment",
89 network
->filename
, name
, kind_string
);
91 *ret
= netdev_ref(netdev
);
95 static int network_resolve_stacked_netdevs(Network
*network
) {
101 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
) {
102 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
104 if (network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
) <= 0)
107 r
= hashmap_ensure_put(&network
->stacked_netdevs
, &string_hash_ops
, netdev
->ifname
, netdev
);
111 log_warning_errno(r
, "%s: Failed to add NetDev '%s' to network, ignoring: %m",
112 network
->filename
, (const char *) name
);
120 int network_verify(Network
*network
) {
124 assert(network
->manager
);
125 assert(network
->filename
);
127 if (net_match_is_empty(&network
->match
) && !network
->conditions
)
128 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
129 "%s: No valid settings found in the [Match] section, ignoring file. "
130 "To match all interfaces, add Name=* in the [Match] section.",
133 /* skip out early if configuration does not match the environment */
134 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
135 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
136 "%s: Conditions in the file do not match the system environment, skipping.",
139 if (network
->keep_master
) {
140 if (network
->batadv_name
)
141 log_warning("%s: BatmanAdvanced= set with KeepMaster= enabled, ignoring BatmanAdvanced=.",
143 if (network
->bond_name
)
144 log_warning("%s: Bond= set with KeepMaster= enabled, ignoring Bond=.",
146 if (network
->bridge_name
)
147 log_warning("%s: Bridge= set with KeepMaster= enabled, ignoring Bridge=.",
149 if (network
->vrf_name
)
150 log_warning("%s: VRF= set with KeepMaster= enabled, ignoring VRF=.",
153 network
->batadv_name
= mfree(network
->batadv_name
);
154 network
->bond_name
= mfree(network
->bond_name
);
155 network
->bridge_name
= mfree(network
->bridge_name
);
156 network
->vrf_name
= mfree(network
->vrf_name
);
159 (void) network_resolve_netdev_one(network
, network
->batadv_name
, NETDEV_KIND_BATADV
, &network
->batadv
);
160 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
161 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
162 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
163 r
= network_resolve_stacked_netdevs(network
);
167 /* Free unnecessary entries. */
168 network
->batadv_name
= mfree(network
->batadv_name
);
169 network
->bond_name
= mfree(network
->bond_name
);
170 network
->bridge_name
= mfree(network
->bridge_name
);
171 network
->vrf_name
= mfree(network
->vrf_name
);
172 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
175 /* Bonding slave does not support addressing. */
176 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
177 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
179 network
->link_local
= ADDRESS_FAMILY_NO
;
181 if (!ordered_hashmap_isempty(network
->addresses_by_section
))
182 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
184 if (!hashmap_isempty(network
->routes_by_section
))
185 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
188 network
->addresses_by_section
= ordered_hashmap_free(network
->addresses_by_section
);
189 network
->routes_by_section
= hashmap_free(network
->routes_by_section
);
192 if (network
->link_local
< 0) {
193 network
->link_local
= ADDRESS_FAMILY_IPV6
;
195 if (network
->keep_master
|| network
->bridge
)
196 network
->link_local
= ADDRESS_FAMILY_NO
;
200 HASHMAP_FOREACH(netdev
, network
->stacked_netdevs
) {
203 if (netdev
->kind
== NETDEV_KIND_MACVLAN
)
205 else if (netdev
->kind
== NETDEV_KIND_MACVTAP
)
210 if (m
->mode
== NETDEV_MACVLAN_MODE_PASSTHRU
)
211 network
->link_local
= ADDRESS_FAMILY_NO
;
213 /* There won't be a passthru MACVLAN/MACVTAP if there's already one in another mode */
219 if (network
->ipv6ll_address_gen_mode
== IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
)
220 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_IPV6
, false);
222 if (in6_addr_is_set(&network
->ipv6ll_stable_secret
) &&
223 network
->ipv6ll_address_gen_mode
< 0)
224 network
->ipv6ll_address_gen_mode
= IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
;
226 network_adjust_ipv6_proxy_ndp(network
);
227 network_adjust_ndisc(network
);
228 network_adjust_dhcp(network
);
229 network_adjust_radv(network
);
230 network_adjust_bridge_vlan(network
);
232 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
233 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
234 "Disabling UseMTU=.", network
->filename
);
235 network
->dhcp_use_mtu
= false;
238 if (network
->dhcp_critical
>= 0) {
239 if (network
->keep_configuration
>= 0) {
240 if (network
->manager
->keep_configuration
< 0)
241 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
242 "Ignoring CriticalConnection=.", network
->filename
);
243 } else if (network
->dhcp_critical
)
244 /* CriticalConnection=yes also preserve foreign static configurations. */
245 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
247 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
250 if (!strv_isempty(network
->bind_carrier
)) {
251 if (!IN_SET(network
->activation_policy
, _ACTIVATION_POLICY_INVALID
, ACTIVATION_POLICY_BOUND
))
252 log_warning("%s: ActivationPolicy=bound is required with BindCarrier=. "
253 "Setting ActivationPolicy=bound.", network
->filename
);
254 network
->activation_policy
= ACTIVATION_POLICY_BOUND
;
255 } else if (network
->activation_policy
== ACTIVATION_POLICY_BOUND
) {
256 log_warning("%s: ActivationPolicy=bound requires BindCarrier=. "
257 "Ignoring ActivationPolicy=bound.", network
->filename
);
258 network
->activation_policy
= ACTIVATION_POLICY_UP
;
261 if (network
->activation_policy
== _ACTIVATION_POLICY_INVALID
)
262 network
->activation_policy
= ACTIVATION_POLICY_UP
;
264 if (network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_UP
) {
265 if (network
->ignore_carrier_loss_set
&& network
->ignore_carrier_loss_usec
< USEC_INFINITY
)
266 log_warning("%s: IgnoreCarrierLoss=no or finite timespan conflicts with ActivationPolicy=always-up. "
267 "Setting IgnoreCarrierLoss=yes.", network
->filename
);
268 network
->ignore_carrier_loss_set
= true;
269 network
->ignore_carrier_loss_usec
= USEC_INFINITY
;
272 if (!network
->ignore_carrier_loss_set
) /* Set implied default. */
273 network
->ignore_carrier_loss_usec
= network
->configure_without_carrier
? USEC_INFINITY
: 0;
275 if (IN_SET(network
->activation_policy
, ACTIVATION_POLICY_DOWN
, ACTIVATION_POLICY_ALWAYS_DOWN
, ACTIVATION_POLICY_MANUAL
)) {
276 if (network
->required_for_online
< 0 ||
277 (network
->required_for_online
== true && network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_DOWN
)) {
278 log_debug("%s: Setting RequiredForOnline=no because ActivationPolicy=%s.", network
->filename
,
279 activation_policy_to_string(network
->activation_policy
));
280 network
->required_for_online
= false;
281 } else if (network
->required_for_online
== true)
282 log_warning("%s: RequiredForOnline=yes and ActivationPolicy=%s, "
283 "this may cause a delay at boot.", network
->filename
,
284 activation_policy_to_string(network
->activation_policy
));
287 if (network
->required_for_online
< 0)
288 network
->required_for_online
= true;
290 if (network
->keep_configuration
< 0)
291 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
293 if (network
->ipv6_proxy_ndp
== 0 && !set_isempty(network
->ipv6_proxy_ndp_addresses
)) {
294 log_warning("%s: IPv6ProxyNDP= is disabled. Ignoring IPv6ProxyNDPAddress=.", network
->filename
);
295 network
->ipv6_proxy_ndp_addresses
= set_free_free(network
->ipv6_proxy_ndp_addresses
);
298 r
= network_drop_invalid_addresses(network
);
300 return r
; /* network_drop_invalid_addresses() logs internally. */
301 network_drop_invalid_routes(network
);
302 r
= network_drop_invalid_nexthops(network
);
305 network_drop_invalid_bridge_fdb_entries(network
);
306 network_drop_invalid_bridge_mdb_entries(network
);
307 r
= network_drop_invalid_neighbors(network
);
310 network_drop_invalid_address_labels(network
);
311 network_drop_invalid_routing_policy_rules(network
);
312 network_drop_invalid_qdisc(network
);
313 network_drop_invalid_tclass(network
);
314 r
= sr_iov_drop_invalid_sections(UINT32_MAX
, network
->sr_iov_by_section
);
316 return r
; /* sr_iov_drop_invalid_sections() logs internally. */
317 network_drop_invalid_static_leases(network
);
322 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
323 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
324 _cleanup_(network_unrefp
) Network
*network
= NULL
;
325 const char *dropin_dirname
;
332 r
= null_or_empty_path(filename
);
334 return log_warning_errno(r
, "Failed to check if \"%s\" is empty: %m", filename
);
336 log_debug("Skipping empty file: %s", filename
);
340 fname
= strdup(filename
);
344 name
= strdup(basename(filename
));
348 d
= strrchr(name
, '.');
350 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
), "Invalid file name: %s", filename
);
354 dropin_dirname
= strjoina(name
, ".network.d");
356 network
= new(Network
, 1);
360 *network
= (Network
) {
361 .filename
= TAKE_PTR(fname
),
362 .name
= TAKE_PTR(name
),
367 .required_for_online
= -1,
368 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_INVALID
,
369 .activation_policy
= _ACTIVATION_POLICY_INVALID
,
376 .keep_configuration
= manager
->keep_configuration
,
378 .use_domains
= _USE_DOMAINS_INVALID
,
380 .compat_dhcp_use_domains
= _USE_DOMAINS_INVALID
,
381 .compat_dhcp_use_dns
= -1,
382 .compat_dhcp_use_ntp
= -1,
384 .dhcp_duid
.type
= _DUID_TYPE_INVALID
,
387 .dhcp_routes_to_ntp
= true,
388 .dhcp_use_sip
= true,
389 .dhcp_use_captive_portal
= true,
391 .dhcp_routes_to_dns
= true,
392 .dhcp_use_domains
= _USE_DOMAINS_INVALID
,
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,
409 .dhcp6_use_domains
= _USE_DOMAINS_INVALID
,
410 .dhcp6_use_hostname
= true,
412 .dhcp6_use_captive_portal
= true,
413 .dhcp6_use_rapid_commit
= true,
414 .dhcp6_send_hostname
= true,
415 .dhcp6_duid
.type
= _DUID_TYPE_INVALID
,
416 .dhcp6_client_start_mode
= _DHCP6_CLIENT_START_MODE_INVALID
,
417 .dhcp6_send_release
= true,
420 .dhcp_pd_announce
= true,
421 .dhcp_pd_assign
= true,
422 .dhcp_pd_manage_temporary_address
= true,
423 .dhcp_pd_subnet_id
= -1,
424 .dhcp_pd_route_metric
= DHCP6PD_ROUTE_METRIC
,
426 .dhcp_server_bind_to_interface
= true,
427 .dhcp_server_emit
[SD_DHCP_LEASE_DNS
].emit
= true,
428 .dhcp_server_emit
[SD_DHCP_LEASE_NTP
].emit
= true,
429 .dhcp_server_emit
[SD_DHCP_LEASE_SIP
].emit
= true,
430 .dhcp_server_emit_router
= true,
431 .dhcp_server_emit_timezone
= true,
432 .dhcp_server_rapid_commit
= true,
433 .dhcp_server_persist_leases
= -1,
435 .router_lifetime_usec
= RADV_DEFAULT_ROUTER_LIFETIME_USEC
,
436 .router_dns_lifetime_usec
= RADV_DEFAULT_VALID_LIFETIME_USEC
,
437 .router_emit_dns
= true,
438 .router_emit_domains
= true,
444 .allow_port_to_be_root
= -1,
446 .multicast_flood
= -1,
447 .multicast_to_unicast
= -1,
448 .neighbor_suppression
= -1,
450 .bridge_proxy_arp
= -1,
451 .bridge_proxy_arp_wifi
= -1,
452 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
453 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
455 .bridge_vlan_pvid
= BRIDGE_VLAN_KEEP_PVID
,
457 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
458 .lldp_multicast_mode
= _SD_LLDP_MULTICAST_MODE_INVALID
,
460 .dns_default_route
= -1,
461 .llmnr
= RESOLVE_SUPPORT_YES
,
462 .mdns
= RESOLVE_SUPPORT_NO
,
463 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
464 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
466 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
467 .link_local
= _ADDRESS_FAMILY_INVALID
,
468 .ipv6ll_address_gen_mode
= _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID
,
470 .ip_forwarding
= { -1, -1, },
471 .ipv4_accept_local
= -1,
472 .ipv4_route_localnet
= -1,
473 .ipv6_privacy_extensions
= _IPV6_PRIVACY_EXTENSIONS_INVALID
,
474 .ipv6_dad_transmits
= -1,
475 .ipv6_proxy_ndp
= -1,
477 .proxy_arp_pvlan
= -1,
478 .ipv4_rp_filter
= _IP_REVERSE_PATH_FILTER_INVALID
,
481 .ndisc_use_redirect
= true,
483 .ndisc_use_gateway
= true,
484 .ndisc_use_captive_portal
= true,
485 .ndisc_use_route_prefix
= true,
486 .ndisc_use_autonomous_prefix
= true,
487 .ndisc_use_onlink_prefix
= true,
488 .ndisc_use_mtu
= true,
489 .ndisc_use_hop_limit
= true,
490 .ndisc_use_reachable_time
= true,
491 .ndisc_use_retransmission_time
= true,
492 .ndisc_use_domains
= _USE_DOMAINS_INVALID
,
493 .ndisc_route_table
= RT_TABLE_MAIN
,
494 .ndisc_route_metric_high
= IPV6RA_ROUTE_METRIC_HIGH
,
495 .ndisc_route_metric_medium
= IPV6RA_ROUTE_METRIC_MEDIUM
,
496 .ndisc_route_metric_low
= IPV6RA_ROUTE_METRIC_LOW
,
497 .ndisc_start_dhcp6_client
= IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
,
499 .can_termination
= -1,
501 .ipoib_mode
= _IP_OVER_INFINIBAND_MODE_INVALID
,
505 r
= config_parse_many(
506 STRV_MAKE_CONST(filename
), NETWORK_DIRS
, dropin_dirname
, /* root = */ NULL
,
514 "RoutingPolicyRule\0"
517 "DHCP\0" /* compat */
520 "DHCPv6PrefixDelegation\0" /* compat */
521 "DHCPPrefixDelegation\0"
523 "DHCPServerStaticLease\0"
525 "IPv6NDPProxyAddress\0"
531 "IPv6PrefixDelegation\0"
536 "TrafficControlQueueingDiscipline\0"
542 "DeficitRoundRobinScheduler\0"
543 "DeficitRoundRobinSchedulerClass\0"
544 "EnhancedTransmissionSelection\0"
546 "FairQueueingControlledDelay\0"
548 "GenericRandomEarlyDetection\0"
549 "HeavyHitterFilter\0"
550 "HierarchyTokenBucket\0"
551 "HierarchyTokenBucketClass\0"
557 "QuickFairQueueing\0"
558 "QuickFairQueueingClass\0"
559 "StochasticFairBlue\0"
560 "StochasticFairnessQueueing\0"
561 "TokenBucketFilter\0"
562 "TrivialLinkEqualizer\0",
563 config_item_perf_lookup
, network_network_gperf_lookup
,
566 &network
->stats_by_path
,
569 return r
; /* config_parse_many() logs internally. */
571 r
= network_add_ipv4ll_route(network
);
573 return log_warning_errno(r
, "%s: Failed to add IPv4LL route: %m", network
->filename
);
575 r
= network_add_default_route_on_device(network
);
577 return log_warning_errno(r
, "%s: Failed to add default route on device: %m",
580 r
= network_verify(network
);
582 return r
; /* network_verify() logs internally. */
584 r
= ordered_hashmap_ensure_put(networks
, &string_hash_ops
, network
->name
, network
);
586 return log_warning_errno(r
, "%s: Failed to store configuration into hashmap: %m", filename
);
592 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
593 _cleanup_strv_free_
char **files
= NULL
;
598 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
600 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
602 return log_error_errno(r
, "Failed to enumerate network files: %m");
604 STRV_FOREACH(f
, files
)
605 (void) network_load_one(manager
, networks
, *f
);
610 int network_reload(Manager
*manager
) {
611 OrderedHashmap
*new_networks
= NULL
;
617 r
= network_load(manager
, &new_networks
);
621 ORDERED_HASHMAP_FOREACH(n
, new_networks
) {
622 r
= network_get_by_name(manager
, n
->name
, &old
);
624 log_debug("Found new .network file: %s", n
->filename
);
628 if (!stats_by_path_equal(n
->stats_by_path
, old
->stats_by_path
)) {
629 log_debug("Found updated .network file: %s", n
->filename
);
633 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
641 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
642 manager
->networks
= new_networks
;
644 r
= manager_build_dhcp_pd_subnet_ids(manager
);
648 r
= manager_build_nexthop_ids(manager
);
655 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
660 int manager_build_dhcp_pd_subnet_ids(Manager
*manager
) {
666 set_clear(manager
->dhcp_pd_subnet_ids
);
668 ORDERED_HASHMAP_FOREACH(n
, manager
->networks
) {
675 if (n
->dhcp_pd_subnet_id
< 0)
678 r
= set_ensure_put(&manager
->dhcp_pd_subnet_ids
, &uint64_hash_ops
, &n
->dhcp_pd_subnet_id
);
686 static Network
*network_free(Network
*network
) {
691 free(network
->filename
);
692 free(network
->description
);
693 strv_free(network
->dropins
);
694 hashmap_free(network
->stats_by_path
);
697 net_match_clear(&network
->match
);
698 condition_free_list(network
->conditions
);
701 strv_free(network
->bind_carrier
);
704 strv_free(network
->ntp
);
707 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
708 in_addr_full_free(network
->dns
[i
]);
710 ordered_set_free(network
->search_domains
);
711 ordered_set_free(network
->route_domains
);
712 set_free_free(network
->dnssec_negative_trust_anchors
);
715 free(network
->dhcp_server_relay_agent_circuit_id
);
716 free(network
->dhcp_server_relay_agent_remote_id
);
717 free(network
->dhcp_server_boot_server_name
);
718 free(network
->dhcp_server_boot_filename
);
719 free(network
->dhcp_server_timezone
);
720 free(network
->dhcp_server_uplink_name
);
721 for (sd_dhcp_lease_server_type_t t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
722 free(network
->dhcp_server_emit
[t
].addresses
);
723 ordered_hashmap_free(network
->dhcp_server_send_options
);
724 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
727 free(network
->dhcp_vendor_class_identifier
);
728 free(network
->dhcp_mudurl
);
729 free(network
->dhcp_hostname
);
730 free(network
->dhcp_label
);
731 set_free(network
->dhcp_deny_listed_ip
);
732 set_free(network
->dhcp_allow_listed_ip
);
733 strv_free(network
->dhcp_user_class
);
734 set_free(network
->dhcp_request_options
);
735 ordered_hashmap_free(network
->dhcp_client_send_options
);
736 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
737 free(network
->dhcp_netlabel
);
738 nft_set_context_clear(&network
->dhcp_nft_set_context
);
741 free(network
->dhcp6_mudurl
);
742 free(network
->dhcp6_hostname
);
743 strv_free(network
->dhcp6_user_class
);
744 strv_free(network
->dhcp6_vendor_class
);
745 set_free(network
->dhcp6_request_options
);
746 ordered_hashmap_free(network
->dhcp6_client_send_options
);
747 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
748 free(network
->dhcp6_netlabel
);
749 nft_set_context_clear(&network
->dhcp6_nft_set_context
);
752 free(network
->dhcp_pd_uplink_name
);
753 set_free(network
->dhcp_pd_tokens
);
754 free(network
->dhcp_pd_netlabel
);
755 nft_set_context_clear(&network
->dhcp_pd_nft_set_context
);
757 /* Router advertisement */
758 ordered_set_free(network
->router_search_domains
);
759 free(network
->router_dns
);
760 free(network
->router_uplink_name
);
763 set_free(network
->ndisc_deny_listed_router
);
764 set_free(network
->ndisc_allow_listed_router
);
765 set_free(network
->ndisc_deny_listed_prefix
);
766 set_free(network
->ndisc_allow_listed_prefix
);
767 set_free(network
->ndisc_deny_listed_route_prefix
);
768 set_free(network
->ndisc_allow_listed_route_prefix
);
769 set_free(network
->ndisc_tokens
);
770 free(network
->ndisc_netlabel
);
771 nft_set_context_clear(&network
->ndisc_nft_set_context
);
774 free(network
->lldp_mudurl
);
777 free(network
->batadv_name
);
778 free(network
->bridge_name
);
779 free(network
->bond_name
);
780 free(network
->vrf_name
);
781 hashmap_free_free_key(network
->stacked_netdev_names
);
782 netdev_unref(network
->bridge
);
783 netdev_unref(network
->bond
);
784 netdev_unref(network
->vrf
);
785 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
788 set_free_free(network
->ipv6_proxy_ndp_addresses
);
789 ordered_hashmap_free(network
->addresses_by_section
);
790 hashmap_free(network
->routes_by_section
);
791 ordered_hashmap_free(network
->nexthops_by_section
);
792 hashmap_free_with_destructor(network
->bridge_fdb_entries_by_section
, bridge_fdb_free
);
793 hashmap_free_with_destructor(network
->bridge_mdb_entries_by_section
, bridge_mdb_free
);
794 ordered_hashmap_free(network
->neighbors_by_section
);
795 hashmap_free_with_destructor(network
->address_labels_by_section
, address_label_free
);
796 hashmap_free_with_destructor(network
->prefixes_by_section
, prefix_free
);
797 hashmap_free_with_destructor(network
->route_prefixes_by_section
, route_prefix_free
);
798 hashmap_free_with_destructor(network
->pref64_prefixes_by_section
, pref64_prefix_free
);
799 hashmap_free_with_destructor(network
->rules_by_section
, routing_policy_rule_free
);
800 hashmap_free_with_destructor(network
->dhcp_static_leases_by_section
, dhcp_static_lease_free
);
801 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
802 hashmap_free_with_destructor(network
->qdiscs_by_section
, qdisc_free
);
803 hashmap_free_with_destructor(network
->tclasses_by_section
, tclass_free
);
805 return mfree(network
);
808 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
810 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
817 network
= ordered_hashmap_get(manager
->networks
, name
);
826 bool network_has_static_ipv6_configurations(Network
*network
) {
835 ORDERED_HASHMAP_FOREACH(address
, network
->addresses_by_section
)
836 if (address
->family
== AF_INET6
)
839 HASHMAP_FOREACH(route
, network
->routes_by_section
)
840 if (route
->family
== AF_INET6
)
843 HASHMAP_FOREACH(fdb
, network
->bridge_fdb_entries_by_section
)
844 if (fdb
->family
== AF_INET6
)
847 HASHMAP_FOREACH(mdb
, network
->bridge_mdb_entries_by_section
)
848 if (mdb
->family
== AF_INET6
)
851 ORDERED_HASHMAP_FOREACH(neighbor
, network
->neighbors_by_section
)
852 if (neighbor
->family
== AF_INET6
)
855 if (!hashmap_isempty(network
->address_labels_by_section
))
858 if (!hashmap_isempty(network
->prefixes_by_section
))
861 if (!hashmap_isempty(network
->route_prefixes_by_section
))
864 if (!hashmap_isempty(network
->pref64_prefixes_by_section
))
870 int config_parse_stacked_netdev(
872 const char *filename
,
875 unsigned section_line
,
882 _cleanup_free_
char *name
= NULL
;
883 NetDevKind kind
= ltype
;
884 Hashmap
**h
= ASSERT_PTR(data
);
900 _NETDEV_KIND_TUNNEL
));
902 if (!ifname_valid(rvalue
)) {
903 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
904 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
908 name
= strdup(rvalue
);
912 r
= hashmap_ensure_put(h
, &string_hash_ops
, name
, INT_TO_PTR(kind
));
916 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
917 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
919 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
920 "NetDev '%s' specified twice, ignoring.", name
);
927 int config_parse_required_for_online(
929 const char *filename
,
932 unsigned section_line
,
939 Network
*network
= ASSERT_PTR(userdata
);
946 if (isempty(rvalue
)) {
947 network
->required_for_online
= -1;
948 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_INVALID
;
952 r
= parse_operational_state_range(rvalue
, &network
->required_operstate_for_online
);
954 r
= parse_boolean(rvalue
);
956 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
957 "Failed to parse %s= setting, ignoring assignment: %s",
962 network
->required_for_online
= r
;
963 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
967 network
->required_for_online
= true;
971 int config_parse_link_group(
973 const char *filename
,
976 unsigned section_line
,
983 Network
*network
= ASSERT_PTR(userdata
);
991 if (isempty(rvalue
)) {
996 r
= safe_atoi32(rvalue
, &group
);
998 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
999 "Failed to parse Group=, ignoring assignment: %s", rvalue
);
1004 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1005 "Value of Group= must be in the range 0…2147483647, ignoring assignment: %s", rvalue
);
1009 network
->group
= group
;
1013 int config_parse_ignore_carrier_loss(
1015 const char *filename
,
1017 const char *section
,
1018 unsigned section_line
,
1025 Network
*network
= ASSERT_PTR(userdata
);
1033 if (isempty(rvalue
)) {
1034 network
->ignore_carrier_loss_set
= false;
1038 r
= parse_boolean(rvalue
);
1040 network
->ignore_carrier_loss_set
= true;
1041 network
->ignore_carrier_loss_usec
= r
> 0 ? USEC_INFINITY
: 0;
1045 r
= parse_sec(rvalue
, &usec
);
1047 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1048 "Failed to parse %s=, ignoring assignment: %s", lvalue
, rvalue
);
1052 network
->ignore_carrier_loss_set
= true;
1053 network
->ignore_carrier_loss_usec
= usec
;
1057 DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online
, link_required_address_family
, AddressFamily
,
1058 "Failed to parse RequiredFamilyForOnline= setting");
1060 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1061 "Failed to parse KeepConfiguration= setting");
1063 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1064 [KEEP_CONFIGURATION_NO
] = "no",
1065 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1066 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1067 [KEEP_CONFIGURATION_STATIC
] = "static",
1068 [KEEP_CONFIGURATION_YES
] = "yes",
1071 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1073 static const char* const activation_policy_table
[_ACTIVATION_POLICY_MAX
] = {
1074 [ACTIVATION_POLICY_UP
] = "up",
1075 [ACTIVATION_POLICY_ALWAYS_UP
] = "always-up",
1076 [ACTIVATION_POLICY_MANUAL
] = "manual",
1077 [ACTIVATION_POLICY_ALWAYS_DOWN
] = "always-down",
1078 [ACTIVATION_POLICY_DOWN
] = "down",
1079 [ACTIVATION_POLICY_BOUND
] = "bound",
1082 DEFINE_STRING_TABLE_LOOKUP(activation_policy
, ActivationPolicy
);
1083 DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy
, activation_policy
, ActivationPolicy
, "Failed to parse activation policy");