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 128
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
);
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
);
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
);
354 log_debug("Skipping empty file: %s", filename
);
358 fname
= strdup(filename
);
362 name
= strdup(basename(filename
));
366 d
= strrchr(name
, '.');
372 dropin_dirname
= strjoina(name
, ".network.d");
374 network
= new(Network
, 1);
378 *network
= (Network
) {
379 .filename
= TAKE_PTR(fname
),
380 .name
= TAKE_PTR(name
),
385 .required_for_online
= -1,
386 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
387 .activation_policy
= _ACTIVATION_POLICY_INVALID
,
393 .keep_configuration
= manager
->keep_configuration
,
395 .dhcp_duid
.type
= _DUID_TYPE_INVALID
,
397 .dhcp_use_ntp
= true,
398 .dhcp_routes_to_ntp
= true,
399 .dhcp_use_sip
= true,
400 .dhcp_use_dns
= true,
401 .dhcp_routes_to_dns
= true,
402 .dhcp_use_hostname
= true,
403 .dhcp_use_routes
= true,
404 .dhcp_use_gateway
= -1,
405 .dhcp_send_hostname
= true,
406 .dhcp_send_release
= true,
407 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
408 .dhcp_client_identifier
= _DHCP_CLIENT_ID_INVALID
,
409 .dhcp_route_table
= RT_TABLE_MAIN
,
410 .dhcp_ip_service_type
= -1,
411 .dhcp_broadcast
= -1,
413 .dhcp6_use_address
= true,
414 .dhcp6_use_pd_prefix
= true,
415 .dhcp6_use_dns
= true,
416 .dhcp6_use_hostname
= true,
417 .dhcp6_use_ntp
= 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
= DHCP_ROUTE_METRIC
,
485 .ipv6_accept_ra_start_dhcp6_client
= IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
,
487 .can_termination
= -1,
489 .ipoib_mode
= _IP_OVER_INFINIBAND_MODE_INVALID
,
493 r
= config_parse_many(
494 STRV_MAKE_CONST(filename
), NETWORK_DIRS
, dropin_dirname
,
502 "RoutingPolicyRule\0"
505 "DHCP\0" /* compat */
508 "DHCPv6PrefixDelegation\0" /* compat */
509 "DHCPPrefixDelegation\0"
511 "DHCPServerStaticLease\0"
513 "IPv6NDPProxyAddress\0"
519 "IPv6PrefixDelegation\0"
523 "TrafficControlQueueingDiscipline\0"
529 "DeficitRoundRobinScheduler\0"
530 "DeficitRoundRobinSchedulerClass\0"
531 "EnhancedTransmissionSelection\0"
533 "FairQueueingControlledDelay\0"
535 "GenericRandomEarlyDetection\0"
536 "HeavyHitterFilter\0"
537 "HierarchyTokenBucket\0"
538 "HierarchyTokenBucketClass\0"
544 "QuickFairQueueing\0"
545 "QuickFairQueueingClass\0"
546 "StochasticFairBlue\0"
547 "StochasticFairnessQueueing\0"
548 "TokenBucketFilter\0"
549 "TrivialLinkEqualizer\0",
550 config_item_perf_lookup
, network_network_gperf_lookup
,
553 &network
->stats_by_path
);
557 r
= network_add_ipv4ll_route(network
);
559 return log_warning_errno(r
, "%s: Failed to add IPv4LL route: %m", network
->filename
);
561 r
= network_add_default_route_on_device(network
);
563 return log_warning_errno(r
, "%s: Failed to add default route on device: %m",
566 r
= network_verify(network
);
570 /* Ignore .network files that do not match the conditions. */
573 r
= ordered_hashmap_ensure_put(networks
, &string_hash_ops
, network
->name
, network
);
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 r
= network_load_one(manager
, networks
, *f
);
596 return log_error_errno(r
, "Failed to load %s: %m", *f
);
602 static bool stats_by_path_equal(Hashmap
*a
, Hashmap
*b
) {
603 struct stat
*st_a
, *st_b
;
609 if (hashmap_size(a
) != hashmap_size(b
))
612 HASHMAP_FOREACH_KEY(st_a
, path
, a
) {
613 st_b
= hashmap_get(b
, path
);
617 if (!stat_inode_unmodified(st_a
, st_b
))
624 int network_reload(Manager
*manager
) {
625 OrderedHashmap
*new_networks
= NULL
;
631 r
= network_load(manager
, &new_networks
);
635 ORDERED_HASHMAP_FOREACH(n
, new_networks
) {
636 r
= network_get_by_name(manager
, n
->name
, &old
);
638 log_debug("Found new .network file: %s", n
->filename
);
642 if (!stats_by_path_equal(n
->stats_by_path
, old
->stats_by_path
)) {
643 log_debug("Found updated .network file: %s", n
->filename
);
647 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
655 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
656 manager
->networks
= new_networks
;
658 return manager_build_dhcp_pd_subnet_ids(manager
);
661 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
666 int manager_build_dhcp_pd_subnet_ids(Manager
*manager
) {
672 set_clear(manager
->dhcp_pd_subnet_ids
);
674 ORDERED_HASHMAP_FOREACH(n
, manager
->networks
) {
681 if (n
->dhcp_pd_subnet_id
< 0)
684 r
= set_ensure_put(&manager
->dhcp_pd_subnet_ids
, &uint64_hash_ops
, &n
->dhcp_pd_subnet_id
);
692 static Network
*network_free(Network
*network
) {
696 free(network
->filename
);
697 hashmap_free(network
->stats_by_path
);
699 net_match_clear(&network
->match
);
700 condition_free_list(network
->conditions
);
702 free(network
->dhcp_server_relay_agent_circuit_id
);
703 free(network
->dhcp_server_relay_agent_remote_id
);
704 free(network
->dhcp_server_boot_server_name
);
705 free(network
->dhcp_server_boot_filename
);
707 free(network
->description
);
708 free(network
->dhcp_vendor_class_identifier
);
709 free(network
->dhcp_mudurl
);
710 strv_free(network
->dhcp_user_class
);
711 free(network
->dhcp_hostname
);
712 free(network
->dhcp_label
);
713 set_free(network
->dhcp_deny_listed_ip
);
714 set_free(network
->dhcp_allow_listed_ip
);
715 set_free(network
->dhcp_request_options
);
716 set_free(network
->dhcp6_request_options
);
717 free(network
->dhcp6_mudurl
);
718 strv_free(network
->dhcp6_user_class
);
719 strv_free(network
->dhcp6_vendor_class
);
721 strv_free(network
->ntp
);
722 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
723 in_addr_full_free(network
->dns
[i
]);
725 ordered_set_free(network
->search_domains
);
726 ordered_set_free(network
->route_domains
);
727 strv_free(network
->bind_carrier
);
729 ordered_set_free(network
->router_search_domains
);
730 free(network
->router_dns
);
731 set_free(network
->ndisc_deny_listed_router
);
732 set_free(network
->ndisc_allow_listed_router
);
733 set_free(network
->ndisc_deny_listed_prefix
);
734 set_free(network
->ndisc_allow_listed_prefix
);
735 set_free(network
->ndisc_deny_listed_route_prefix
);
736 set_free(network
->ndisc_allow_listed_route_prefix
);
738 free(network
->batadv_name
);
739 free(network
->bridge_name
);
740 free(network
->bond_name
);
741 free(network
->vrf_name
);
742 hashmap_free_free_key(network
->stacked_netdev_names
);
743 netdev_unref(network
->bridge
);
744 netdev_unref(network
->bond
);
745 netdev_unref(network
->vrf
);
746 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
748 set_free_free(network
->ipv6_proxy_ndp_addresses
);
749 ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
750 hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
751 hashmap_free_with_destructor(network
->nexthops_by_section
, nexthop_free
);
752 hashmap_free_with_destructor(network
->bridge_fdb_entries_by_section
, bridge_fdb_free
);
753 hashmap_free_with_destructor(network
->bridge_mdb_entries_by_section
, bridge_mdb_free
);
754 hashmap_free_with_destructor(network
->neighbors_by_section
, neighbor_free
);
755 hashmap_free_with_destructor(network
->address_labels_by_section
, address_label_free
);
756 hashmap_free_with_destructor(network
->prefixes_by_section
, prefix_free
);
757 hashmap_free_with_destructor(network
->route_prefixes_by_section
, route_prefix_free
);
758 hashmap_free_with_destructor(network
->rules_by_section
, routing_policy_rule_free
);
759 hashmap_free_with_destructor(network
->dhcp_static_leases_by_section
, dhcp_static_lease_free
);
760 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
761 hashmap_free_with_destructor(network
->qdiscs_by_section
, qdisc_free
);
762 hashmap_free_with_destructor(network
->tclasses_by_section
, tclass_free
);
766 free(network
->dhcp_server_timezone
);
767 free(network
->dhcp_server_uplink_name
);
768 free(network
->router_uplink_name
);
769 free(network
->dhcp_pd_uplink_name
);
771 for (sd_dhcp_lease_server_type_t t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
772 free(network
->dhcp_server_emit
[t
].addresses
);
774 set_free_free(network
->dnssec_negative_trust_anchors
);
776 free(network
->lldp_mudurl
);
778 ordered_hashmap_free(network
->dhcp_client_send_options
);
779 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
780 ordered_hashmap_free(network
->dhcp_server_send_options
);
781 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
782 ordered_hashmap_free(network
->dhcp6_client_send_options
);
783 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
784 set_free(network
->dhcp_pd_tokens
);
785 set_free(network
->ndisc_tokens
);
787 return mfree(network
);
790 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
792 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
799 network
= ordered_hashmap_get(manager
->networks
, name
);
808 bool network_has_static_ipv6_configurations(Network
*network
) {
817 ORDERED_HASHMAP_FOREACH(address
, network
->addresses_by_section
)
818 if (address
->family
== AF_INET6
)
821 HASHMAP_FOREACH(route
, network
->routes_by_section
)
822 if (route
->family
== AF_INET6
)
825 HASHMAP_FOREACH(fdb
, network
->bridge_fdb_entries_by_section
)
826 if (fdb
->family
== AF_INET6
)
829 HASHMAP_FOREACH(mdb
, network
->bridge_mdb_entries_by_section
)
830 if (mdb
->family
== AF_INET6
)
833 HASHMAP_FOREACH(neighbor
, network
->neighbors_by_section
)
834 if (neighbor
->family
== AF_INET6
)
837 if (!hashmap_isempty(network
->address_labels_by_section
))
840 if (!hashmap_isempty(network
->prefixes_by_section
))
843 if (!hashmap_isempty(network
->route_prefixes_by_section
))
849 int config_parse_stacked_netdev(
851 const char *filename
,
854 unsigned section_line
,
861 _cleanup_free_
char *name
= NULL
;
862 NetDevKind kind
= ltype
;
880 _NETDEV_KIND_TUNNEL
));
882 if (!ifname_valid(rvalue
)) {
883 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
884 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
888 name
= strdup(rvalue
);
892 r
= hashmap_ensure_put(h
, &string_hash_ops
, name
, INT_TO_PTR(kind
));
896 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
897 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
899 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
900 "NetDev '%s' specified twice, ignoring.", name
);
907 int config_parse_domains(
909 const char *filename
,
912 unsigned section_line
,
919 Network
*n
= userdata
;
927 if (isempty(rvalue
)) {
928 n
->search_domains
= ordered_set_free(n
->search_domains
);
929 n
->route_domains
= ordered_set_free(n
->route_domains
);
933 for (const char *p
= rvalue
;;) {
934 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
938 r
= extract_first_word(&p
, &w
, NULL
, 0);
942 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
943 "Failed to extract search or route domain, ignoring: %s", rvalue
);
949 is_route
= w
[0] == '~';
950 domain
= is_route
? w
+ 1 : w
;
952 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
953 /* If the root domain appears as is, or the special token "*" is found, we'll
954 * consider this as routing domain, unconditionally. */
956 domain
= "."; /* make sure we don't allow empty strings, thus write the root
959 r
= dns_name_normalize(domain
, 0, &normalized
);
961 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
962 "'%s' is not a valid domain name, ignoring.", domain
);
968 if (is_localhost(domain
)) {
969 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
970 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
976 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
977 r
= ordered_set_put_strdup(set
, domain
);
985 int config_parse_timezone(
987 const char *filename
,
990 unsigned section_line
,
1005 if (isempty(rvalue
)) {
1010 r
= verify_timezone(rvalue
, LOG_WARNING
);
1012 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1013 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1017 return free_and_strdup_warn(tz
, rvalue
);
1020 int config_parse_dns(
1022 const char *filename
,
1024 const char *section
,
1025 unsigned section_line
,
1032 Network
*n
= userdata
;
1040 if (isempty(rvalue
)) {
1041 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
1042 in_addr_full_free(n
->dns
[i
]);
1043 n
->dns
= mfree(n
->dns
);
1048 for (const char *p
= rvalue
;;) {
1049 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
1050 _cleanup_free_
char *w
= NULL
;
1051 struct in_addr_full
**m
;
1053 r
= extract_first_word(&p
, &w
, NULL
, 0);
1057 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1058 "Invalid syntax, ignoring: %s", rvalue
);
1064 r
= in_addr_full_new_from_string(w
, &dns
);
1066 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1067 "Failed to parse dns server address, ignoring: %s", w
);
1071 if (IN_SET(dns
->port
, 53, 853))
1074 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
1078 m
[n
->n_dns
++] = TAKE_PTR(dns
);
1083 int config_parse_dnssec_negative_trust_anchors(
1085 const char *filename
,
1087 const char *section
,
1088 unsigned section_line
,
1103 if (isempty(rvalue
)) {
1104 *nta
= set_free_free(*nta
);
1108 for (const char *p
= rvalue
;;) {
1109 _cleanup_free_
char *w
= NULL
;
1111 r
= extract_first_word(&p
, &w
, NULL
, 0);
1115 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1116 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1122 r
= dns_name_is_valid(w
);
1124 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1125 "%s is not a valid domain name, ignoring.", w
);
1129 r
= set_ensure_consume(nta
, &dns_name_hash_ops
, TAKE_PTR(w
));
1135 int config_parse_ntp(
1137 const char *filename
,
1139 const char *section
,
1140 unsigned section_line
,
1155 if (isempty(rvalue
)) {
1160 for (const char *p
= rvalue
;;) {
1161 _cleanup_free_
char *w
= NULL
;
1163 r
= extract_first_word(&p
, &w
, NULL
, 0);
1167 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1168 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1174 r
= dns_name_is_valid_or_address(w
);
1176 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1177 "%s is not a valid domain name or IP address, ignoring.", w
);
1181 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1182 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1183 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1184 MAX_NTP_SERVERS
, w
);
1188 r
= strv_consume(l
, TAKE_PTR(w
));
1194 int config_parse_required_for_online(
1196 const char *filename
,
1198 const char *section
,
1199 unsigned section_line
,
1206 Network
*network
= userdata
;
1207 LinkOperationalStateRange range
;
1208 bool required
= true;
1216 if (isempty(rvalue
)) {
1217 network
->required_for_online
= -1;
1218 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1222 r
= parse_operational_state_range(rvalue
, &range
);
1224 r
= parse_boolean(rvalue
);
1226 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1227 "Failed to parse %s= setting, ignoring assignment: %s",
1233 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1236 network
->required_for_online
= required
;
1237 network
->required_operstate_for_online
= range
;
1242 int config_parse_link_group(
1244 const char *filename
,
1246 const char *section
,
1247 unsigned section_line
,
1254 Network
*network
= userdata
;
1263 if (isempty(rvalue
)) {
1264 network
->group
= -1;
1268 r
= safe_atoi32(rvalue
, &group
);
1270 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1271 "Failed to parse Group=, ignoring assignment: %s", rvalue
);
1276 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1277 "Value of Group= must be in the range 0…2147483647, ignoring assignment: %s", rvalue
);
1281 network
->group
= group
;
1285 int config_parse_ignore_carrier_loss(
1287 const char *filename
,
1289 const char *section
,
1290 unsigned section_line
,
1297 Network
*network
= userdata
;
1306 if (isempty(rvalue
)) {
1307 network
->ignore_carrier_loss_set
= false;
1311 r
= parse_boolean(rvalue
);
1313 network
->ignore_carrier_loss_set
= true;
1314 network
->ignore_carrier_loss_usec
= r
> 0 ? USEC_INFINITY
: 0;
1318 r
= parse_sec(rvalue
, &usec
);
1320 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1321 "Failed to parse %s=, ignoring assignment: %s", lvalue
, rvalue
);
1325 network
->ignore_carrier_loss_set
= true;
1326 network
->ignore_carrier_loss_usec
= usec
;
1330 DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online
, link_required_address_family
, AddressFamily
,
1331 "Failed to parse RequiredFamilyForOnline= setting");
1333 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1334 "Failed to parse KeepConfiguration= setting");
1336 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1337 [KEEP_CONFIGURATION_NO
] = "no",
1338 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1339 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1340 [KEEP_CONFIGURATION_STATIC
] = "static",
1341 [KEEP_CONFIGURATION_YES
] = "yes",
1344 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1346 static const char* const activation_policy_table
[_ACTIVATION_POLICY_MAX
] = {
1347 [ACTIVATION_POLICY_UP
] = "up",
1348 [ACTIVATION_POLICY_ALWAYS_UP
] = "always-up",
1349 [ACTIVATION_POLICY_MANUAL
] = "manual",
1350 [ACTIVATION_POLICY_ALWAYS_DOWN
] = "always-down",
1351 [ACTIVATION_POLICY_DOWN
] = "down",
1352 [ACTIVATION_POLICY_BOUND
] = "bound",
1355 DEFINE_STRING_TABLE_LOOKUP(activation_policy
, ActivationPolicy
);
1356 DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy
, activation_policy
, ActivationPolicy
, "Failed to parse activation policy");