1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <netinet/in.h>
5 #include <linux/netdevice.h>
8 #include "alloc-util.h"
9 #include "conf-files.h"
10 #include "conf-parser.h"
11 #include "dns-domain.h"
13 #include "hostname-util.h"
14 #include "in-addr-util.h"
15 #include "net-condition.h"
16 #include "netdev/macvlan.h"
17 #include "networkd-address-label.h"
18 #include "networkd-address.h"
19 #include "networkd-bridge-fdb.h"
20 #include "networkd-bridge-mdb.h"
21 #include "networkd-dhcp-common.h"
22 #include "networkd-dhcp-server-static-lease.h"
23 #include "networkd-dhcp-server.h"
24 #include "networkd-ipv6-proxy-ndp.h"
25 #include "networkd-manager.h"
26 #include "networkd-ndisc.h"
27 #include "networkd-neighbor.h"
28 #include "networkd-network.h"
29 #include "networkd-nexthop.h"
30 #include "networkd-radv.h"
31 #include "networkd-route.h"
32 #include "networkd-routing-policy-rule.h"
33 #include "networkd-sriov.h"
34 #include "parse-util.h"
35 #include "path-lookup.h"
37 #include "radv-internal.h"
39 #include "socket-util.h"
40 #include "stat-util.h"
41 #include "string-table.h"
42 #include "string-util.h"
47 /* Let's assume that anything above this number is a user misconfiguration. */
48 #define MAX_NTP_SERVERS 128U
50 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret
) {
51 const char *kind_string
;
55 /* For test-networkd-conf, the check must be earlier than the assertions. */
60 assert(network
->manager
);
61 assert(network
->filename
);
64 if (kind
== _NETDEV_KIND_TUNNEL
)
65 kind_string
= "tunnel";
67 kind_string
= netdev_kind_to_string(kind
);
69 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
70 "%s: Invalid NetDev kind of %s, ignoring assignment.",
71 network
->filename
, name
);
74 r
= netdev_get(network
->manager
, name
, &netdev
);
76 return log_warning_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
77 network
->filename
, name
);
79 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
85 NETDEV_KIND_IP6GRETAP
,
91 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
92 "%s: NetDev %s is not a %s, ignoring assignment",
93 network
->filename
, name
, kind_string
);
95 *ret
= netdev_ref(netdev
);
99 static int network_resolve_stacked_netdevs(Network
*network
) {
105 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
) {
106 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
108 if (network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
) <= 0)
111 r
= hashmap_ensure_put(&network
->stacked_netdevs
, &string_hash_ops
, netdev
->ifname
, netdev
);
115 log_warning_errno(r
, "%s: Failed to add NetDev '%s' to network, ignoring: %m",
116 network
->filename
, (const char *) name
);
124 int network_verify(Network
*network
) {
128 assert(network
->manager
);
129 assert(network
->filename
);
131 if (net_match_is_empty(&network
->match
) && !network
->conditions
)
132 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
133 "%s: No valid settings found in the [Match] section, ignoring file. "
134 "To match all interfaces, add Name=* in the [Match] section.",
137 /* skip out early if configuration does not match the environment */
138 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
139 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
140 "%s: Conditions in the file do not match the system environment, skipping.",
143 if (network
->keep_master
) {
144 if (network
->batadv_name
)
145 log_warning("%s: BatmanAdvanced= set with KeepMaster= enabled, ignoring BatmanAdvanced=.",
147 if (network
->bond_name
)
148 log_warning("%s: Bond= set with KeepMaster= enabled, ignoring Bond=.",
150 if (network
->bridge_name
)
151 log_warning("%s: Bridge= set with KeepMaster= enabled, ignoring Bridge=.",
153 if (network
->vrf_name
)
154 log_warning("%s: VRF= set with KeepMaster= enabled, ignoring VRF=.",
157 network
->batadv_name
= mfree(network
->batadv_name
);
158 network
->bond_name
= mfree(network
->bond_name
);
159 network
->bridge_name
= mfree(network
->bridge_name
);
160 network
->vrf_name
= mfree(network
->vrf_name
);
163 (void) network_resolve_netdev_one(network
, network
->batadv_name
, NETDEV_KIND_BATADV
, &network
->batadv
);
164 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
165 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
166 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
167 r
= network_resolve_stacked_netdevs(network
);
171 /* Free unnecessary entries. */
172 network
->batadv_name
= mfree(network
->batadv_name
);
173 network
->bond_name
= mfree(network
->bond_name
);
174 network
->bridge_name
= mfree(network
->bridge_name
);
175 network
->vrf_name
= mfree(network
->vrf_name
);
176 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
179 /* Bonding slave does not support addressing. */
180 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
181 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
183 network
->link_local
= ADDRESS_FAMILY_NO
;
185 if (network
->dhcp_server
) {
186 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
188 network
->dhcp_server
= false;
190 if (!ordered_hashmap_isempty(network
->addresses_by_section
))
191 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
193 if (!hashmap_isempty(network
->routes_by_section
))
194 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
197 network
->addresses_by_section
= ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
198 network
->routes_by_section
= hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
201 if (network
->link_local
< 0) {
202 network
->link_local
= ADDRESS_FAMILY_IPV6
;
204 if (network
->keep_master
|| network
->bridge
)
205 network
->link_local
= ADDRESS_FAMILY_NO
;
209 HASHMAP_FOREACH(netdev
, network
->stacked_netdevs
) {
212 if (netdev
->kind
== NETDEV_KIND_MACVLAN
)
214 else if (netdev
->kind
== NETDEV_KIND_MACVTAP
)
221 if (m
->mode
== NETDEV_MACVLAN_MODE_PASSTHRU
)
222 network
->link_local
= ADDRESS_FAMILY_NO
;
224 /* There won't be a passthru MACVLAN/MACVTAP if there's already one in another mode */
230 if (network
->ipv6ll_address_gen_mode
== IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
)
231 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_IPV6
, false);
233 if (in6_addr_is_set(&network
->ipv6ll_stable_secret
) &&
234 network
->ipv6ll_address_gen_mode
< 0)
235 network
->ipv6ll_address_gen_mode
= IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
;
237 /* IPMasquerade implies IPForward */
238 network
->ip_forward
|= network
->ip_masquerade
;
240 network_adjust_ipv6_proxy_ndp(network
);
241 network_adjust_ipv6_accept_ra(network
);
242 network_adjust_dhcp(network
);
243 network_adjust_radv(network
);
244 network_adjust_bridge_vlan(network
);
246 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
247 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
248 "Disabling UseMTU=.", network
->filename
);
249 network
->dhcp_use_mtu
= false;
252 if (network
->dhcp_critical
>= 0) {
253 if (network
->keep_configuration
>= 0) {
254 if (network
->manager
->keep_configuration
< 0)
255 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
256 "Ignoring CriticalConnection=.", network
->filename
);
257 } else if (network
->dhcp_critical
)
258 /* CriticalConnection=yes also preserve foreign static configurations. */
259 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
261 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
264 if (!strv_isempty(network
->bind_carrier
)) {
265 if (!IN_SET(network
->activation_policy
, _ACTIVATION_POLICY_INVALID
, ACTIVATION_POLICY_BOUND
))
266 log_warning("%s: ActivationPolicy=bound is required with BindCarrier=. "
267 "Setting ActivationPolicy=bound.", network
->filename
);
268 network
->activation_policy
= ACTIVATION_POLICY_BOUND
;
269 } else if (network
->activation_policy
== ACTIVATION_POLICY_BOUND
) {
270 log_warning("%s: ActivationPolicy=bound requires BindCarrier=. "
271 "Ignoring ActivationPolicy=bound.", network
->filename
);
272 network
->activation_policy
= ACTIVATION_POLICY_UP
;
275 if (network
->activation_policy
== _ACTIVATION_POLICY_INVALID
)
276 network
->activation_policy
= ACTIVATION_POLICY_UP
;
278 if (network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_UP
) {
279 if (network
->ignore_carrier_loss_set
&& network
->ignore_carrier_loss_usec
< USEC_INFINITY
)
280 log_warning("%s: IgnoreCarrierLoss=no or finite timespan conflicts with ActivationPolicy=always-up. "
281 "Setting IgnoreCarrierLoss=yes.", network
->filename
);
282 network
->ignore_carrier_loss_set
= true;
283 network
->ignore_carrier_loss_usec
= USEC_INFINITY
;
286 if (!network
->ignore_carrier_loss_set
) {
287 network
->ignore_carrier_loss_set
= true;
288 network
->ignore_carrier_loss_usec
= network
->configure_without_carrier
? USEC_INFINITY
: 0;
291 if (IN_SET(network
->activation_policy
, ACTIVATION_POLICY_DOWN
, ACTIVATION_POLICY_ALWAYS_DOWN
, ACTIVATION_POLICY_MANUAL
)) {
292 if (network
->required_for_online
< 0 ||
293 (network
->required_for_online
== true && network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_DOWN
)) {
294 log_debug("%s: Setting RequiredForOnline=no because ActivationPolicy=%s.", network
->filename
,
295 activation_policy_to_string(network
->activation_policy
));
296 network
->required_for_online
= false;
297 } else if (network
->required_for_online
== true)
298 log_warning("%s: RequiredForOnline=yes and ActivationPolicy=%s, "
299 "this may cause a delay at boot.", network
->filename
,
300 activation_policy_to_string(network
->activation_policy
));
303 if (network
->required_for_online
< 0)
304 network
->required_for_online
= true;
306 if (network
->keep_configuration
< 0)
307 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
309 if (network
->ipv6_proxy_ndp
== 0 && !set_isempty(network
->ipv6_proxy_ndp_addresses
)) {
310 log_warning("%s: IPv6ProxyNDP= is disabled. Ignoring IPv6ProxyNDPAddress=.", network
->filename
);
311 network
->ipv6_proxy_ndp_addresses
= set_free_free(network
->ipv6_proxy_ndp_addresses
);
314 r
= network_drop_invalid_addresses(network
);
316 return r
; /* network_drop_invalid_addresses() logs internally. */
317 network_drop_invalid_routes(network
);
318 network_drop_invalid_nexthops(network
);
319 network_drop_invalid_bridge_fdb_entries(network
);
320 network_drop_invalid_bridge_mdb_entries(network
);
321 network_drop_invalid_neighbors(network
);
322 network_drop_invalid_address_labels(network
);
323 network_drop_invalid_prefixes(network
);
324 network_drop_invalid_route_prefixes(network
);
325 network_drop_invalid_routing_policy_rules(network
);
326 network_drop_invalid_qdisc(network
);
327 network_drop_invalid_tclass(network
);
328 r
= sr_iov_drop_invalid_sections(UINT32_MAX
, network
->sr_iov_by_section
);
330 return r
; /* sr_iov_drop_invalid_sections() logs internally. */
331 network_drop_invalid_static_leases(network
);
333 network_adjust_dhcp_server(network
);
338 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
339 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
340 _cleanup_(network_unrefp
) Network
*network
= NULL
;
341 const char *dropin_dirname
;
348 r
= null_or_empty_path(filename
);
350 return log_warning_errno(r
, "Failed to check if \"%s\" is empty: %m", filename
);
352 log_debug("Skipping empty file: %s", filename
);
356 fname
= strdup(filename
);
360 name
= strdup(basename(filename
));
364 d
= strrchr(name
, '.');
366 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
), "Invalid file name: %s", filename
);
370 dropin_dirname
= strjoina(name
, ".network.d");
372 network
= new(Network
, 1);
376 *network
= (Network
) {
377 .filename
= TAKE_PTR(fname
),
378 .name
= TAKE_PTR(name
),
383 .required_for_online
= -1,
384 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
385 .activation_policy
= _ACTIVATION_POLICY_INVALID
,
392 .keep_configuration
= manager
->keep_configuration
,
394 .dhcp_duid
.type
= _DUID_TYPE_INVALID
,
396 .dhcp_use_ntp
= true,
397 .dhcp_routes_to_ntp
= true,
398 .dhcp_use_sip
= true,
399 .dhcp_use_dns
= true,
400 .dhcp_routes_to_dns
= true,
401 .dhcp_use_hostname
= true,
402 .dhcp_use_routes
= true,
403 .dhcp_use_gateway
= -1,
404 .dhcp_send_hostname
= true,
405 .dhcp_send_release
= true,
406 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
407 .dhcp_client_identifier
= _DHCP_CLIENT_ID_INVALID
,
408 .dhcp_route_table
= RT_TABLE_MAIN
,
409 .dhcp_ip_service_type
= -1,
410 .dhcp_broadcast
= -1,
412 .dhcp6_use_address
= true,
413 .dhcp6_use_pd_prefix
= true,
414 .dhcp6_use_dns
= true,
415 .dhcp6_use_hostname
= true,
416 .dhcp6_use_ntp
= true,
417 .dhcp6_use_rapid_commit
= true,
418 .dhcp6_duid
.type
= _DUID_TYPE_INVALID
,
419 .dhcp6_client_start_mode
= _DHCP6_CLIENT_START_MODE_INVALID
,
422 .dhcp_pd_announce
= true,
423 .dhcp_pd_assign
= true,
424 .dhcp_pd_manage_temporary_address
= true,
425 .dhcp_pd_subnet_id
= -1,
426 .dhcp_pd_route_metric
= DHCP6PD_ROUTE_METRIC
,
428 .dhcp_server_bind_to_interface
= true,
429 .dhcp_server_emit
[SD_DHCP_LEASE_DNS
].emit
= true,
430 .dhcp_server_emit
[SD_DHCP_LEASE_NTP
].emit
= true,
431 .dhcp_server_emit
[SD_DHCP_LEASE_SIP
].emit
= true,
432 .dhcp_server_emit_router
= true,
433 .dhcp_server_emit_timezone
= true,
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 .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_NO
,
471 .ipv6_dad_transmits
= -1,
472 .ipv6_hop_limit
= -1,
473 .ipv6_proxy_ndp
= -1,
476 .ipv6_accept_ra
= -1,
477 .ipv6_accept_ra_use_dns
= true,
478 .ipv6_accept_ra_use_gateway
= true,
479 .ipv6_accept_ra_use_route_prefix
= true,
480 .ipv6_accept_ra_use_autonomous_prefix
= true,
481 .ipv6_accept_ra_use_onlink_prefix
= true,
482 .ipv6_accept_ra_use_mtu
= true,
483 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
484 .ipv6_accept_ra_route_metric_high
= IPV6RA_ROUTE_METRIC_HIGH
,
485 .ipv6_accept_ra_route_metric_medium
= IPV6RA_ROUTE_METRIC_MEDIUM
,
486 .ipv6_accept_ra_route_metric_low
= IPV6RA_ROUTE_METRIC_LOW
,
487 .ipv6_accept_ra_start_dhcp6_client
= IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
,
489 .can_termination
= -1,
491 .ipoib_mode
= _IP_OVER_INFINIBAND_MODE_INVALID
,
495 r
= config_parse_many(
496 STRV_MAKE_CONST(filename
), NETWORK_DIRS
, dropin_dirname
,
504 "RoutingPolicyRule\0"
507 "DHCP\0" /* compat */
510 "DHCPv6PrefixDelegation\0" /* compat */
511 "DHCPPrefixDelegation\0"
513 "DHCPServerStaticLease\0"
515 "IPv6NDPProxyAddress\0"
521 "IPv6PrefixDelegation\0"
525 "TrafficControlQueueingDiscipline\0"
531 "DeficitRoundRobinScheduler\0"
532 "DeficitRoundRobinSchedulerClass\0"
533 "EnhancedTransmissionSelection\0"
535 "FairQueueingControlledDelay\0"
537 "GenericRandomEarlyDetection\0"
538 "HeavyHitterFilter\0"
539 "HierarchyTokenBucket\0"
540 "HierarchyTokenBucketClass\0"
546 "QuickFairQueueing\0"
547 "QuickFairQueueingClass\0"
548 "StochasticFairBlue\0"
549 "StochasticFairnessQueueing\0"
550 "TokenBucketFilter\0"
551 "TrivialLinkEqualizer\0",
552 config_item_perf_lookup
, network_network_gperf_lookup
,
555 &network
->stats_by_path
,
558 return r
; /* config_parse_many() logs internally. */
560 r
= network_add_ipv4ll_route(network
);
562 return log_warning_errno(r
, "%s: Failed to add IPv4LL route: %m", network
->filename
);
564 r
= network_add_default_route_on_device(network
);
566 return log_warning_errno(r
, "%s: Failed to add default route on device: %m",
569 r
= network_verify(network
);
571 return r
; /* network_verify() logs internally. */
573 r
= ordered_hashmap_ensure_put(networks
, &string_hash_ops
, network
->name
, network
);
575 return log_warning_errno(r
, "%s: Failed to store configuration into hashmap: %m", filename
);
581 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
582 _cleanup_strv_free_
char **files
= NULL
;
587 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
589 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
591 return log_error_errno(r
, "Failed to enumerate network files: %m");
593 STRV_FOREACH(f
, files
)
594 (void) network_load_one(manager
, networks
, *f
);
599 int network_reload(Manager
*manager
) {
600 OrderedHashmap
*new_networks
= NULL
;
606 r
= network_load(manager
, &new_networks
);
610 ORDERED_HASHMAP_FOREACH(n
, new_networks
) {
611 r
= network_get_by_name(manager
, n
->name
, &old
);
613 log_debug("Found new .network file: %s", n
->filename
);
617 if (!stats_by_path_equal(n
->stats_by_path
, old
->stats_by_path
)) {
618 log_debug("Found updated .network file: %s", n
->filename
);
622 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
630 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
631 manager
->networks
= new_networks
;
633 return manager_build_dhcp_pd_subnet_ids(manager
);
636 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
641 int manager_build_dhcp_pd_subnet_ids(Manager
*manager
) {
647 set_clear(manager
->dhcp_pd_subnet_ids
);
649 ORDERED_HASHMAP_FOREACH(n
, manager
->networks
) {
656 if (n
->dhcp_pd_subnet_id
< 0)
659 r
= set_ensure_put(&manager
->dhcp_pd_subnet_ids
, &uint64_hash_ops
, &n
->dhcp_pd_subnet_id
);
667 static Network
*network_free(Network
*network
) {
672 free(network
->filename
);
673 free(network
->description
);
674 hashmap_free(network
->stats_by_path
);
677 net_match_clear(&network
->match
);
678 condition_free_list(network
->conditions
);
681 strv_free(network
->bind_carrier
);
684 strv_free(network
->ntp
);
687 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
688 in_addr_full_free(network
->dns
[i
]);
690 ordered_set_free(network
->search_domains
);
691 ordered_set_free(network
->route_domains
);
692 set_free_free(network
->dnssec_negative_trust_anchors
);
695 free(network
->dhcp_server_relay_agent_circuit_id
);
696 free(network
->dhcp_server_relay_agent_remote_id
);
697 free(network
->dhcp_server_boot_server_name
);
698 free(network
->dhcp_server_boot_filename
);
699 free(network
->dhcp_server_timezone
);
700 free(network
->dhcp_server_uplink_name
);
701 for (sd_dhcp_lease_server_type_t t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
702 free(network
->dhcp_server_emit
[t
].addresses
);
703 ordered_hashmap_free(network
->dhcp_server_send_options
);
704 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
707 free(network
->dhcp_vendor_class_identifier
);
708 free(network
->dhcp_mudurl
);
709 free(network
->dhcp_hostname
);
710 free(network
->dhcp_label
);
711 set_free(network
->dhcp_deny_listed_ip
);
712 set_free(network
->dhcp_allow_listed_ip
);
713 strv_free(network
->dhcp_user_class
);
714 set_free(network
->dhcp_request_options
);
715 ordered_hashmap_free(network
->dhcp_client_send_options
);
716 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
717 free(network
->dhcp_netlabel
);
720 free(network
->dhcp6_mudurl
);
721 strv_free(network
->dhcp6_user_class
);
722 strv_free(network
->dhcp6_vendor_class
);
723 set_free(network
->dhcp6_request_options
);
724 ordered_hashmap_free(network
->dhcp6_client_send_options
);
725 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
726 free(network
->dhcp6_netlabel
);
729 free(network
->dhcp_pd_uplink_name
);
730 set_free(network
->dhcp_pd_tokens
);
731 free(network
->dhcp_pd_netlabel
);
733 /* Router advertisement */
734 ordered_set_free(network
->router_search_domains
);
735 free(network
->router_dns
);
736 free(network
->router_uplink_name
);
739 set_free(network
->ndisc_deny_listed_router
);
740 set_free(network
->ndisc_allow_listed_router
);
741 set_free(network
->ndisc_deny_listed_prefix
);
742 set_free(network
->ndisc_allow_listed_prefix
);
743 set_free(network
->ndisc_deny_listed_route_prefix
);
744 set_free(network
->ndisc_allow_listed_route_prefix
);
745 set_free(network
->ndisc_tokens
);
746 free(network
->ndisc_netlabel
);
749 free(network
->lldp_mudurl
);
752 free(network
->batadv_name
);
753 free(network
->bridge_name
);
754 free(network
->bond_name
);
755 free(network
->vrf_name
);
756 hashmap_free_free_key(network
->stacked_netdev_names
);
757 netdev_unref(network
->bridge
);
758 netdev_unref(network
->bond
);
759 netdev_unref(network
->vrf
);
760 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
763 set_free_free(network
->ipv6_proxy_ndp_addresses
);
764 ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
765 hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
766 hashmap_free_with_destructor(network
->nexthops_by_section
, nexthop_free
);
767 hashmap_free_with_destructor(network
->bridge_fdb_entries_by_section
, bridge_fdb_free
);
768 hashmap_free_with_destructor(network
->bridge_mdb_entries_by_section
, bridge_mdb_free
);
769 hashmap_free_with_destructor(network
->neighbors_by_section
, neighbor_free
);
770 hashmap_free_with_destructor(network
->address_labels_by_section
, address_label_free
);
771 hashmap_free_with_destructor(network
->prefixes_by_section
, prefix_free
);
772 hashmap_free_with_destructor(network
->route_prefixes_by_section
, route_prefix_free
);
773 hashmap_free_with_destructor(network
->rules_by_section
, routing_policy_rule_free
);
774 hashmap_free_with_destructor(network
->dhcp_static_leases_by_section
, dhcp_static_lease_free
);
775 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
776 hashmap_free_with_destructor(network
->qdiscs_by_section
, qdisc_free
);
777 hashmap_free_with_destructor(network
->tclasses_by_section
, tclass_free
);
779 return mfree(network
);
782 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
784 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
791 network
= ordered_hashmap_get(manager
->networks
, name
);
800 bool network_has_static_ipv6_configurations(Network
*network
) {
809 ORDERED_HASHMAP_FOREACH(address
, network
->addresses_by_section
)
810 if (address
->family
== AF_INET6
)
813 HASHMAP_FOREACH(route
, network
->routes_by_section
)
814 if (route
->family
== AF_INET6
)
817 HASHMAP_FOREACH(fdb
, network
->bridge_fdb_entries_by_section
)
818 if (fdb
->family
== AF_INET6
)
821 HASHMAP_FOREACH(mdb
, network
->bridge_mdb_entries_by_section
)
822 if (mdb
->family
== AF_INET6
)
825 HASHMAP_FOREACH(neighbor
, network
->neighbors_by_section
)
826 if (neighbor
->family
== AF_INET6
)
829 if (!hashmap_isempty(network
->address_labels_by_section
))
832 if (!hashmap_isempty(network
->prefixes_by_section
))
835 if (!hashmap_isempty(network
->route_prefixes_by_section
))
841 int config_parse_stacked_netdev(
843 const char *filename
,
846 unsigned section_line
,
853 _cleanup_free_
char *name
= NULL
;
854 NetDevKind kind
= ltype
;
855 Hashmap
**h
= ASSERT_PTR(data
);
871 _NETDEV_KIND_TUNNEL
));
873 if (!ifname_valid(rvalue
)) {
874 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
875 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
879 name
= strdup(rvalue
);
883 r
= hashmap_ensure_put(h
, &string_hash_ops
, name
, INT_TO_PTR(kind
));
887 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
888 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
890 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
891 "NetDev '%s' specified twice, ignoring.", name
);
898 int config_parse_domains(
900 const char *filename
,
903 unsigned section_line
,
910 Network
*n
= ASSERT_PTR(userdata
);
917 if (isempty(rvalue
)) {
918 n
->search_domains
= ordered_set_free(n
->search_domains
);
919 n
->route_domains
= ordered_set_free(n
->route_domains
);
923 for (const char *p
= rvalue
;;) {
924 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
928 r
= extract_first_word(&p
, &w
, NULL
, 0);
932 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
933 "Failed to extract search or route domain, ignoring: %s", rvalue
);
939 is_route
= w
[0] == '~';
940 domain
= is_route
? w
+ 1 : w
;
942 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
943 /* If the root domain appears as is, or the special token "*" is found, we'll
944 * consider this as routing domain, unconditionally. */
946 domain
= "."; /* make sure we don't allow empty strings, thus write the root
949 r
= dns_name_normalize(domain
, 0, &normalized
);
951 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
952 "'%s' is not a valid domain name, ignoring.", domain
);
958 if (is_localhost(domain
)) {
959 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
960 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
966 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
967 r
= ordered_set_put_strdup(set
, domain
);
975 int config_parse_timezone(
977 const char *filename
,
980 unsigned section_line
,
987 char **tz
= ASSERT_PTR(data
);
994 if (isempty(rvalue
)) {
999 r
= verify_timezone(rvalue
, LOG_WARNING
);
1001 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1002 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1006 return free_and_strdup_warn(tz
, rvalue
);
1009 int config_parse_dns(
1011 const char *filename
,
1013 const char *section
,
1014 unsigned section_line
,
1021 Network
*n
= ASSERT_PTR(userdata
);
1028 if (isempty(rvalue
)) {
1029 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
1030 in_addr_full_free(n
->dns
[i
]);
1031 n
->dns
= mfree(n
->dns
);
1036 for (const char *p
= rvalue
;;) {
1037 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
1038 _cleanup_free_
char *w
= NULL
;
1039 struct in_addr_full
**m
;
1041 r
= extract_first_word(&p
, &w
, NULL
, 0);
1045 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1046 "Invalid syntax, ignoring: %s", rvalue
);
1052 r
= in_addr_full_new_from_string(w
, &dns
);
1054 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1055 "Failed to parse dns server address, ignoring: %s", w
);
1059 if (IN_SET(dns
->port
, 53, 853))
1062 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
1066 m
[n
->n_dns
++] = TAKE_PTR(dns
);
1071 int config_parse_dnssec_negative_trust_anchors(
1073 const char *filename
,
1075 const char *section
,
1076 unsigned section_line
,
1083 Set
**nta
= ASSERT_PTR(data
);
1090 if (isempty(rvalue
)) {
1091 *nta
= set_free_free(*nta
);
1095 for (const char *p
= rvalue
;;) {
1096 _cleanup_free_
char *w
= NULL
;
1098 r
= extract_first_word(&p
, &w
, NULL
, 0);
1102 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1103 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1109 r
= dns_name_is_valid(w
);
1111 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1112 "%s is not a valid domain name, ignoring.", w
);
1116 r
= set_ensure_consume(nta
, &dns_name_hash_ops
, TAKE_PTR(w
));
1122 int config_parse_ntp(
1124 const char *filename
,
1126 const char *section
,
1127 unsigned section_line
,
1134 char ***l
= ASSERT_PTR(data
);
1141 if (isempty(rvalue
)) {
1146 for (const char *p
= rvalue
;;) {
1147 _cleanup_free_
char *w
= NULL
;
1149 r
= extract_first_word(&p
, &w
, NULL
, 0);
1153 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1154 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1160 r
= dns_name_is_valid_or_address(w
);
1162 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1163 "%s is not a valid domain name or IP address, ignoring.", w
);
1167 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1168 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1169 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1170 MAX_NTP_SERVERS
, w
);
1174 r
= strv_consume(l
, TAKE_PTR(w
));
1180 int config_parse_required_for_online(
1182 const char *filename
,
1184 const char *section
,
1185 unsigned section_line
,
1192 Network
*network
= ASSERT_PTR(userdata
);
1193 LinkOperationalStateRange range
;
1194 bool required
= true;
1201 if (isempty(rvalue
)) {
1202 network
->required_for_online
= -1;
1203 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1207 r
= parse_operational_state_range(rvalue
, &range
);
1209 r
= parse_boolean(rvalue
);
1211 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1212 "Failed to parse %s= setting, ignoring assignment: %s",
1218 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1221 network
->required_for_online
= required
;
1222 network
->required_operstate_for_online
= range
;
1227 int config_parse_link_group(
1229 const char *filename
,
1231 const char *section
,
1232 unsigned section_line
,
1239 Network
*network
= ASSERT_PTR(userdata
);
1247 if (isempty(rvalue
)) {
1248 network
->group
= -1;
1252 r
= safe_atoi32(rvalue
, &group
);
1254 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1255 "Failed to parse Group=, ignoring assignment: %s", rvalue
);
1260 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1261 "Value of Group= must be in the range 0…2147483647, ignoring assignment: %s", rvalue
);
1265 network
->group
= group
;
1269 int config_parse_ignore_carrier_loss(
1271 const char *filename
,
1273 const char *section
,
1274 unsigned section_line
,
1281 Network
*network
= ASSERT_PTR(userdata
);
1289 if (isempty(rvalue
)) {
1290 network
->ignore_carrier_loss_set
= false;
1294 r
= parse_boolean(rvalue
);
1296 network
->ignore_carrier_loss_set
= true;
1297 network
->ignore_carrier_loss_usec
= r
> 0 ? USEC_INFINITY
: 0;
1301 r
= parse_sec(rvalue
, &usec
);
1303 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1304 "Failed to parse %s=, ignoring assignment: %s", lvalue
, rvalue
);
1308 network
->ignore_carrier_loss_set
= true;
1309 network
->ignore_carrier_loss_usec
= usec
;
1313 DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online
, link_required_address_family
, AddressFamily
,
1314 "Failed to parse RequiredFamilyForOnline= setting");
1316 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1317 "Failed to parse KeepConfiguration= setting");
1319 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1320 [KEEP_CONFIGURATION_NO
] = "no",
1321 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1322 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1323 [KEEP_CONFIGURATION_STATIC
] = "static",
1324 [KEEP_CONFIGURATION_YES
] = "yes",
1327 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1329 static const char* const activation_policy_table
[_ACTIVATION_POLICY_MAX
] = {
1330 [ACTIVATION_POLICY_UP
] = "up",
1331 [ACTIVATION_POLICY_ALWAYS_UP
] = "always-up",
1332 [ACTIVATION_POLICY_MANUAL
] = "manual",
1333 [ACTIVATION_POLICY_ALWAYS_DOWN
] = "always-down",
1334 [ACTIVATION_POLICY_DOWN
] = "down",
1335 [ACTIVATION_POLICY_BOUND
] = "bound",
1338 DEFINE_STRING_TABLE_LOOKUP(activation_policy
, ActivationPolicy
);
1339 DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy
, activation_policy
, ActivationPolicy
, "Failed to parse activation policy");