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
;
588 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
590 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
592 return log_error_errno(r
, "Failed to enumerate network files: %m");
594 STRV_FOREACH(f
, files
) {
595 r
= network_load_one(manager
, networks
, *f
);
597 return log_error_errno(r
, "Failed to load %s: %m", *f
);
603 static bool stats_by_path_equal(Hashmap
*a
, Hashmap
*b
) {
604 struct stat
*st_a
, *st_b
;
610 if (hashmap_size(a
) != hashmap_size(b
))
613 HASHMAP_FOREACH_KEY(st_a
, path
, a
) {
614 st_b
= hashmap_get(b
, path
);
618 if (!stat_inode_unmodified(st_a
, st_b
))
625 int network_reload(Manager
*manager
) {
626 OrderedHashmap
*new_networks
= NULL
;
632 r
= network_load(manager
, &new_networks
);
636 ORDERED_HASHMAP_FOREACH(n
, new_networks
) {
637 r
= network_get_by_name(manager
, n
->name
, &old
);
639 log_debug("Found new .network file: %s", n
->filename
);
643 if (!stats_by_path_equal(n
->stats_by_path
, old
->stats_by_path
)) {
644 log_debug("Found updated .network file: %s", n
->filename
);
648 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
656 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
657 manager
->networks
= new_networks
;
659 return manager_build_dhcp_pd_subnet_ids(manager
);
662 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
667 int manager_build_dhcp_pd_subnet_ids(Manager
*manager
) {
673 set_clear(manager
->dhcp_pd_subnet_ids
);
675 ORDERED_HASHMAP_FOREACH(n
, manager
->networks
) {
682 if (n
->dhcp_pd_subnet_id
< 0)
685 r
= set_ensure_put(&manager
->dhcp_pd_subnet_ids
, &uint64_hash_ops
, &n
->dhcp_pd_subnet_id
);
693 static Network
*network_free(Network
*network
) {
697 free(network
->filename
);
698 hashmap_free(network
->stats_by_path
);
700 net_match_clear(&network
->match
);
701 condition_free_list(network
->conditions
);
703 free(network
->dhcp_server_relay_agent_circuit_id
);
704 free(network
->dhcp_server_relay_agent_remote_id
);
705 free(network
->dhcp_server_boot_server_name
);
706 free(network
->dhcp_server_boot_filename
);
708 free(network
->description
);
709 free(network
->dhcp_vendor_class_identifier
);
710 free(network
->dhcp_mudurl
);
711 strv_free(network
->dhcp_user_class
);
712 free(network
->dhcp_hostname
);
713 free(network
->dhcp_label
);
714 set_free(network
->dhcp_deny_listed_ip
);
715 set_free(network
->dhcp_allow_listed_ip
);
716 set_free(network
->dhcp_request_options
);
717 set_free(network
->dhcp6_request_options
);
718 free(network
->dhcp6_mudurl
);
719 strv_free(network
->dhcp6_user_class
);
720 strv_free(network
->dhcp6_vendor_class
);
722 strv_free(network
->ntp
);
723 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
724 in_addr_full_free(network
->dns
[i
]);
726 ordered_set_free(network
->search_domains
);
727 ordered_set_free(network
->route_domains
);
728 strv_free(network
->bind_carrier
);
730 ordered_set_free(network
->router_search_domains
);
731 free(network
->router_dns
);
732 set_free(network
->ndisc_deny_listed_router
);
733 set_free(network
->ndisc_allow_listed_router
);
734 set_free(network
->ndisc_deny_listed_prefix
);
735 set_free(network
->ndisc_allow_listed_prefix
);
736 set_free(network
->ndisc_deny_listed_route_prefix
);
737 set_free(network
->ndisc_allow_listed_route_prefix
);
739 free(network
->batadv_name
);
740 free(network
->bridge_name
);
741 free(network
->bond_name
);
742 free(network
->vrf_name
);
743 hashmap_free_free_key(network
->stacked_netdev_names
);
744 netdev_unref(network
->bridge
);
745 netdev_unref(network
->bond
);
746 netdev_unref(network
->vrf
);
747 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
749 set_free_free(network
->ipv6_proxy_ndp_addresses
);
750 ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
751 hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
752 hashmap_free_with_destructor(network
->nexthops_by_section
, nexthop_free
);
753 hashmap_free_with_destructor(network
->bridge_fdb_entries_by_section
, bridge_fdb_free
);
754 hashmap_free_with_destructor(network
->bridge_mdb_entries_by_section
, bridge_mdb_free
);
755 hashmap_free_with_destructor(network
->neighbors_by_section
, neighbor_free
);
756 hashmap_free_with_destructor(network
->address_labels_by_section
, address_label_free
);
757 hashmap_free_with_destructor(network
->prefixes_by_section
, prefix_free
);
758 hashmap_free_with_destructor(network
->route_prefixes_by_section
, route_prefix_free
);
759 hashmap_free_with_destructor(network
->rules_by_section
, routing_policy_rule_free
);
760 hashmap_free_with_destructor(network
->dhcp_static_leases_by_section
, dhcp_static_lease_free
);
761 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
762 hashmap_free_with_destructor(network
->qdiscs_by_section
, qdisc_free
);
763 hashmap_free_with_destructor(network
->tclasses_by_section
, tclass_free
);
767 free(network
->dhcp_server_timezone
);
768 free(network
->dhcp_server_uplink_name
);
769 free(network
->router_uplink_name
);
770 free(network
->dhcp_pd_uplink_name
);
772 for (sd_dhcp_lease_server_type_t t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
773 free(network
->dhcp_server_emit
[t
].addresses
);
775 set_free_free(network
->dnssec_negative_trust_anchors
);
777 free(network
->lldp_mudurl
);
779 ordered_hashmap_free(network
->dhcp_client_send_options
);
780 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
781 ordered_hashmap_free(network
->dhcp_server_send_options
);
782 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
783 ordered_hashmap_free(network
->dhcp6_client_send_options
);
784 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
785 set_free(network
->dhcp_pd_tokens
);
786 set_free(network
->ndisc_tokens
);
788 return mfree(network
);
791 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
793 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
800 network
= ordered_hashmap_get(manager
->networks
, name
);
809 bool network_has_static_ipv6_configurations(Network
*network
) {
818 ORDERED_HASHMAP_FOREACH(address
, network
->addresses_by_section
)
819 if (address
->family
== AF_INET6
)
822 HASHMAP_FOREACH(route
, network
->routes_by_section
)
823 if (route
->family
== AF_INET6
)
826 HASHMAP_FOREACH(fdb
, network
->bridge_fdb_entries_by_section
)
827 if (fdb
->family
== AF_INET6
)
830 HASHMAP_FOREACH(mdb
, network
->bridge_mdb_entries_by_section
)
831 if (mdb
->family
== AF_INET6
)
834 HASHMAP_FOREACH(neighbor
, network
->neighbors_by_section
)
835 if (neighbor
->family
== AF_INET6
)
838 if (!hashmap_isempty(network
->address_labels_by_section
))
841 if (!hashmap_isempty(network
->prefixes_by_section
))
844 if (!hashmap_isempty(network
->route_prefixes_by_section
))
850 int config_parse_stacked_netdev(
852 const char *filename
,
855 unsigned section_line
,
862 _cleanup_free_
char *name
= NULL
;
863 NetDevKind kind
= ltype
;
881 _NETDEV_KIND_TUNNEL
));
883 if (!ifname_valid(rvalue
)) {
884 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
885 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
889 name
= strdup(rvalue
);
893 r
= hashmap_ensure_put(h
, &string_hash_ops
, name
, INT_TO_PTR(kind
));
897 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
898 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
900 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
901 "NetDev '%s' specified twice, ignoring.", name
);
908 int config_parse_domains(
910 const char *filename
,
913 unsigned section_line
,
920 Network
*n
= userdata
;
928 if (isempty(rvalue
)) {
929 n
->search_domains
= ordered_set_free(n
->search_domains
);
930 n
->route_domains
= ordered_set_free(n
->route_domains
);
934 for (const char *p
= rvalue
;;) {
935 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
939 r
= extract_first_word(&p
, &w
, NULL
, 0);
943 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
944 "Failed to extract search or route domain, ignoring: %s", rvalue
);
950 is_route
= w
[0] == '~';
951 domain
= is_route
? w
+ 1 : w
;
953 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
954 /* If the root domain appears as is, or the special token "*" is found, we'll
955 * consider this as routing domain, unconditionally. */
957 domain
= "."; /* make sure we don't allow empty strings, thus write the root
960 r
= dns_name_normalize(domain
, 0, &normalized
);
962 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
963 "'%s' is not a valid domain name, ignoring.", domain
);
969 if (is_localhost(domain
)) {
970 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
971 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
977 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
978 r
= ordered_set_put_strdup(set
, domain
);
986 int config_parse_timezone(
988 const char *filename
,
991 unsigned section_line
,
1006 if (isempty(rvalue
)) {
1011 r
= verify_timezone(rvalue
, LOG_WARNING
);
1013 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1014 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1018 return free_and_strdup_warn(tz
, rvalue
);
1021 int config_parse_dns(
1023 const char *filename
,
1025 const char *section
,
1026 unsigned section_line
,
1033 Network
*n
= userdata
;
1041 if (isempty(rvalue
)) {
1042 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
1043 in_addr_full_free(n
->dns
[i
]);
1044 n
->dns
= mfree(n
->dns
);
1049 for (const char *p
= rvalue
;;) {
1050 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
1051 _cleanup_free_
char *w
= NULL
;
1052 struct in_addr_full
**m
;
1054 r
= extract_first_word(&p
, &w
, NULL
, 0);
1058 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1059 "Invalid syntax, ignoring: %s", rvalue
);
1065 r
= in_addr_full_new_from_string(w
, &dns
);
1067 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1068 "Failed to parse dns server address, ignoring: %s", w
);
1072 if (IN_SET(dns
->port
, 53, 853))
1075 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
1079 m
[n
->n_dns
++] = TAKE_PTR(dns
);
1084 int config_parse_dnssec_negative_trust_anchors(
1086 const char *filename
,
1088 const char *section
,
1089 unsigned section_line
,
1104 if (isempty(rvalue
)) {
1105 *nta
= set_free_free(*nta
);
1109 for (const char *p
= rvalue
;;) {
1110 _cleanup_free_
char *w
= NULL
;
1112 r
= extract_first_word(&p
, &w
, NULL
, 0);
1116 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1117 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1123 r
= dns_name_is_valid(w
);
1125 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1126 "%s is not a valid domain name, ignoring.", w
);
1130 r
= set_ensure_consume(nta
, &dns_name_hash_ops
, TAKE_PTR(w
));
1136 int config_parse_ntp(
1138 const char *filename
,
1140 const char *section
,
1141 unsigned section_line
,
1156 if (isempty(rvalue
)) {
1161 for (const char *p
= rvalue
;;) {
1162 _cleanup_free_
char *w
= NULL
;
1164 r
= extract_first_word(&p
, &w
, NULL
, 0);
1168 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1169 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1175 r
= dns_name_is_valid_or_address(w
);
1177 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1178 "%s is not a valid domain name or IP address, ignoring.", w
);
1182 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1183 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1184 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1185 MAX_NTP_SERVERS
, w
);
1189 r
= strv_consume(l
, TAKE_PTR(w
));
1195 int config_parse_required_for_online(
1197 const char *filename
,
1199 const char *section
,
1200 unsigned section_line
,
1207 Network
*network
= userdata
;
1208 LinkOperationalStateRange range
;
1209 bool required
= true;
1217 if (isempty(rvalue
)) {
1218 network
->required_for_online
= -1;
1219 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1223 r
= parse_operational_state_range(rvalue
, &range
);
1225 r
= parse_boolean(rvalue
);
1227 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1228 "Failed to parse %s= setting, ignoring assignment: %s",
1234 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1237 network
->required_for_online
= required
;
1238 network
->required_operstate_for_online
= range
;
1243 int config_parse_link_group(
1245 const char *filename
,
1247 const char *section
,
1248 unsigned section_line
,
1255 Network
*network
= userdata
;
1264 if (isempty(rvalue
)) {
1265 network
->group
= -1;
1269 r
= safe_atoi32(rvalue
, &group
);
1271 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1272 "Failed to parse Group=, ignoring assignment: %s", rvalue
);
1277 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1278 "Value of Group= must be in the range 0…2147483647, ignoring assignment: %s", rvalue
);
1282 network
->group
= group
;
1286 int config_parse_ignore_carrier_loss(
1288 const char *filename
,
1290 const char *section
,
1291 unsigned section_line
,
1298 Network
*network
= userdata
;
1307 if (isempty(rvalue
)) {
1308 network
->ignore_carrier_loss_set
= false;
1312 r
= parse_boolean(rvalue
);
1314 network
->ignore_carrier_loss_set
= true;
1315 network
->ignore_carrier_loss_usec
= r
> 0 ? USEC_INFINITY
: 0;
1319 r
= parse_sec(rvalue
, &usec
);
1321 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1322 "Failed to parse %s=, ignoring assignment: %s", lvalue
, rvalue
);
1326 network
->ignore_carrier_loss_set
= true;
1327 network
->ignore_carrier_loss_usec
= usec
;
1331 DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online
, link_required_address_family
, AddressFamily
,
1332 "Failed to parse RequiredFamilyForOnline= setting");
1334 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1335 "Failed to parse KeepConfiguration= setting");
1337 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1338 [KEEP_CONFIGURATION_NO
] = "no",
1339 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1340 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1341 [KEEP_CONFIGURATION_STATIC
] = "static",
1342 [KEEP_CONFIGURATION_YES
] = "yes",
1345 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1347 static const char* const activation_policy_table
[_ACTIVATION_POLICY_MAX
] = {
1348 [ACTIVATION_POLICY_UP
] = "up",
1349 [ACTIVATION_POLICY_ALWAYS_UP
] = "always-up",
1350 [ACTIVATION_POLICY_MANUAL
] = "manual",
1351 [ACTIVATION_POLICY_ALWAYS_DOWN
] = "always-down",
1352 [ACTIVATION_POLICY_DOWN
] = "down",
1353 [ACTIVATION_POLICY_BOUND
] = "bound",
1356 DEFINE_STRING_TABLE_LOOKUP(activation_policy
, ActivationPolicy
);
1357 DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy
, activation_policy
, ActivationPolicy
, "Failed to parse activation policy");