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 "networkd-address-label.h"
17 #include "networkd-address.h"
18 #include "networkd-bridge-fdb.h"
19 #include "networkd-bridge-mdb.h"
20 #include "networkd-dhcp-common.h"
21 #include "networkd-dhcp-server-static-lease.h"
22 #include "networkd-dhcp-server.h"
23 #include "networkd-ipv6-proxy-ndp.h"
24 #include "networkd-manager.h"
25 #include "networkd-ndisc.h"
26 #include "networkd-neighbor.h"
27 #include "networkd-network.h"
28 #include "networkd-nexthop.h"
29 #include "networkd-radv.h"
30 #include "networkd-routing-policy-rule.h"
31 #include "networkd-sriov.h"
32 #include "parse-util.h"
33 #include "path-lookup.h"
35 #include "socket-util.h"
36 #include "stat-util.h"
37 #include "string-table.h"
38 #include "string-util.h"
43 /* Let's assume that anything above this number is a user misconfiguration. */
44 #define MAX_NTP_SERVERS 128
46 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
47 const char *kind_string
;
51 /* For test-networkd-conf, the check must be earlier than the assertions. */
56 assert(network
->manager
);
57 assert(network
->filename
);
60 if (kind
== _NETDEV_KIND_TUNNEL
)
61 kind_string
= "tunnel";
63 kind_string
= netdev_kind_to_string(kind
);
65 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
66 "%s: Invalid NetDev kind of %s, ignoring assignment.",
67 network
->filename
, name
);
70 r
= netdev_get(network
->manager
, name
, &netdev
);
72 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
73 network
->filename
, name
);
75 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
82 NETDEV_KIND_IP6GRETAP
,
87 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
88 "%s: NetDev %s is not a %s, ignoring assignment",
89 network
->filename
, name
, kind_string
);
91 *ret_netdev
= netdev_ref(netdev
);
95 static int network_resolve_stacked_netdevs(Network
*network
) {
101 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
) {
102 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
104 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
108 r
= hashmap_ensure_put(&network
->stacked_netdevs
, &string_hash_ops
, netdev
->ifname
, netdev
);
112 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
113 network
->filename
, (const char *) name
);
121 int network_verify(Network
*network
) {
123 assert(network
->filename
);
125 if (net_match_is_empty(&network
->match
) && !network
->conditions
)
126 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
127 "%s: No valid settings found in the [Match] section, ignoring file. "
128 "To match all interfaces, add Name=* in the [Match] section.",
131 /* skip out early if configuration does not match the environment */
132 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
133 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
134 "%s: Conditions in the file do not match the system environment, skipping.",
137 (void) network_resolve_netdev_one(network
, network
->batadv_name
, NETDEV_KIND_BATADV
, &network
->batadv
);
138 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
139 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
140 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
141 (void) network_resolve_stacked_netdevs(network
);
143 /* Free unnecessary entries. */
144 network
->batadv_name
= mfree(network
->batadv_name
);
145 network
->bond_name
= mfree(network
->bond_name
);
146 network
->bridge_name
= mfree(network
->bridge_name
);
147 network
->vrf_name
= mfree(network
->vrf_name
);
148 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
151 /* Bonding slave does not support addressing. */
152 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
153 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
155 network
->link_local
= ADDRESS_FAMILY_NO
;
157 if (network
->dhcp_server
) {
158 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
160 network
->dhcp_server
= false;
162 if (!ordered_hashmap_isempty(network
->addresses_by_section
))
163 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
165 if (!hashmap_isempty(network
->routes_by_section
))
166 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
169 network
->addresses_by_section
= ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
170 network
->routes_by_section
= hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
173 if (network
->link_local
< 0)
174 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
175 if (network
->ipv6ll_address_gen_mode
== IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
)
176 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_IPV6
, false);
178 if (in6_addr_is_set(&network
->ipv6ll_stable_secret
) &&
179 network
->ipv6ll_address_gen_mode
< 0)
180 network
->ipv6ll_address_gen_mode
= IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
;
182 /* IPMasquerade implies IPForward */
183 network
->ip_forward
|= network
->ip_masquerade
;
185 network_adjust_ipv6_proxy_ndp(network
);
186 network_adjust_ipv6_accept_ra(network
);
187 network_adjust_dhcp(network
);
188 network_adjust_radv(network
);
189 network_adjust_bridge_vlan(network
);
191 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
192 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
193 "Disabling UseMTU=.", network
->filename
);
194 network
->dhcp_use_mtu
= false;
197 if (network
->dhcp_critical
>= 0) {
198 if (network
->keep_configuration
>= 0)
199 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
200 "Ignoring CriticalConnection=.", network
->filename
);
201 else if (network
->dhcp_critical
)
202 /* CriticalConnection=yes also preserve foreign static configurations. */
203 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
205 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
208 if (!strv_isempty(network
->bind_carrier
)) {
209 if (!IN_SET(network
->activation_policy
, _ACTIVATION_POLICY_INVALID
, ACTIVATION_POLICY_BOUND
))
210 log_warning("%s: ActivationPolicy=bound is required with BindCarrier=. "
211 "Setting ActivationPolicy=bound.", network
->filename
);
212 network
->activation_policy
= ACTIVATION_POLICY_BOUND
;
213 } else if (network
->activation_policy
== ACTIVATION_POLICY_BOUND
) {
214 log_warning("%s: ActivationPolicy=bound requires BindCarrier=. "
215 "Ignoring ActivationPolicy=bound.", network
->filename
);
216 network
->activation_policy
= ACTIVATION_POLICY_UP
;
219 if (network
->activation_policy
== _ACTIVATION_POLICY_INVALID
)
220 network
->activation_policy
= ACTIVATION_POLICY_UP
;
222 if (network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_UP
) {
223 if (network
->ignore_carrier_loss
== false)
224 log_warning("%s: IgnoreCarrierLoss=false conflicts with ActivationPolicy=always-up. "
225 "Setting IgnoreCarrierLoss=true.", network
->filename
);
226 network
->ignore_carrier_loss
= true;
229 if (network
->ignore_carrier_loss
< 0)
230 network
->ignore_carrier_loss
= network
->configure_without_carrier
;
232 if (IN_SET(network
->activation_policy
, ACTIVATION_POLICY_DOWN
, ACTIVATION_POLICY_ALWAYS_DOWN
, ACTIVATION_POLICY_MANUAL
)) {
233 if (network
->required_for_online
< 0 ||
234 (network
->required_for_online
== true && network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_DOWN
)) {
235 log_debug("%s: Setting RequiredForOnline=no because ActivationPolicy=%s.", network
->filename
,
236 activation_policy_to_string(network
->activation_policy
));
237 network
->required_for_online
= false;
238 } else if (network
->required_for_online
== true)
239 log_warning("%s: RequiredForOnline=yes and ActivationPolicy=%s, "
240 "this may cause a delay at boot.", network
->filename
,
241 activation_policy_to_string(network
->activation_policy
));
244 if (network
->required_for_online
< 0)
245 network
->required_for_online
= true;
247 if (network
->keep_configuration
< 0)
248 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
250 if (network
->ipv6_proxy_ndp
== 0 && !set_isempty(network
->ipv6_proxy_ndp_addresses
)) {
251 log_warning("%s: IPv6ProxyNDP= is disabled. Ignoring IPv6ProxyNDPAddress=.", network
->filename
);
252 network
->ipv6_proxy_ndp_addresses
= set_free_free(network
->ipv6_proxy_ndp_addresses
);
255 network_drop_invalid_addresses(network
);
256 network_drop_invalid_routes(network
);
257 network_drop_invalid_nexthops(network
);
258 network_drop_invalid_bridge_fdb_entries(network
);
259 network_drop_invalid_bridge_mdb_entries(network
);
260 network_drop_invalid_neighbors(network
);
261 network_drop_invalid_address_labels(network
);
262 network_drop_invalid_prefixes(network
);
263 network_drop_invalid_route_prefixes(network
);
264 network_drop_invalid_routing_policy_rules(network
);
265 network_drop_invalid_traffic_control(network
);
266 network_drop_invalid_sr_iov(network
);
267 network_drop_invalid_static_leases(network
);
269 network_adjust_dhcp_server(network
);
274 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
275 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
276 _cleanup_(network_unrefp
) Network
*network
= NULL
;
277 const char *dropin_dirname
;
284 r
= null_or_empty_path(filename
);
290 log_debug("Skipping empty file: %s", filename
);
294 fname
= strdup(filename
);
298 name
= strdup(basename(filename
));
302 d
= strrchr(name
, '.');
308 dropin_dirname
= strjoina(name
, ".network.d");
310 network
= new(Network
, 1);
314 *network
= (Network
) {
315 .filename
= TAKE_PTR(fname
),
316 .name
= TAKE_PTR(name
),
321 .required_for_online
= -1,
322 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
323 .activation_policy
= _ACTIVATION_POLICY_INVALID
,
329 .ignore_carrier_loss
= -1,
330 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
332 .dhcp_duid
.type
= _DUID_TYPE_INVALID
,
334 .dhcp_use_ntp
= true,
335 .dhcp_routes_to_ntp
= true,
336 .dhcp_use_sip
= true,
337 .dhcp_use_dns
= true,
338 .dhcp_routes_to_dns
= true,
339 .dhcp_use_hostname
= true,
340 .dhcp_use_routes
= true,
341 .dhcp_use_gateway
= -1,
342 .dhcp_send_hostname
= true,
343 .dhcp_send_release
= true,
344 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
345 .dhcp_client_identifier
= _DHCP_CLIENT_ID_INVALID
,
346 .dhcp_route_table
= RT_TABLE_MAIN
,
347 .dhcp_ip_service_type
= -1,
348 .dhcp_broadcast
= -1,
350 .dhcp6_use_address
= true,
351 .dhcp6_use_dns
= true,
352 .dhcp6_use_hostname
= true,
353 .dhcp6_use_ntp
= true,
354 .dhcp6_rapid_commit
= true,
355 .dhcp6_duid
.type
= _DUID_TYPE_INVALID
,
358 .dhcp6_pd_announce
= true,
359 .dhcp6_pd_assign
= true,
360 .dhcp6_pd_manage_temporary_address
= true,
361 .dhcp6_pd_subnet_id
= -1,
363 .dhcp_server_bind_to_interface
= true,
364 .dhcp_server_emit
[SD_DHCP_LEASE_DNS
].emit
= true,
365 .dhcp_server_emit
[SD_DHCP_LEASE_NTP
].emit
= true,
366 .dhcp_server_emit
[SD_DHCP_LEASE_SIP
].emit
= true,
367 .dhcp_server_emit_router
= true,
368 .dhcp_server_emit_timezone
= true,
370 .router_lifetime_usec
= 30 * USEC_PER_MINUTE
,
371 .router_emit_dns
= true,
372 .router_emit_domains
= true,
377 .allow_port_to_be_root
= -1,
379 .multicast_flood
= -1,
380 .multicast_to_unicast
= -1,
381 .neighbor_suppression
= -1,
383 .bridge_proxy_arp
= -1,
384 .bridge_proxy_arp_wifi
= -1,
385 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
386 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
388 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
390 .dns_default_route
= -1,
391 .llmnr
= RESOLVE_SUPPORT_YES
,
392 .mdns
= RESOLVE_SUPPORT_NO
,
393 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
394 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
396 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
397 .link_local
= _ADDRESS_FAMILY_INVALID
,
398 .ipv6ll_address_gen_mode
= _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID
,
400 .ipv4_accept_local
= -1,
401 .ipv4_route_localnet
= -1,
402 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
403 .ipv6_accept_ra
= -1,
404 .ipv6_dad_transmits
= -1,
405 .ipv6_hop_limit
= -1,
406 .ipv6_proxy_ndp
= -1,
409 .ipv6_accept_ra_use_dns
= true,
410 .ipv6_accept_ra_use_autonomous_prefix
= true,
411 .ipv6_accept_ra_use_onlink_prefix
= true,
412 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
413 .ipv6_accept_ra_route_metric
= DHCP_ROUTE_METRIC
,
414 .ipv6_accept_ra_start_dhcp6_client
= IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
,
416 .can_termination
= -1,
419 r
= config_parse_many(
420 STRV_MAKE_CONST(filename
), NETWORK_DIRS
, dropin_dirname
,
428 "RoutingPolicyRule\0"
431 "DHCP\0" /* compat */
434 "DHCPv6PrefixDelegation\0"
436 "DHCPServerStaticLease\0"
438 "IPv6NDPProxyAddress\0"
444 "IPv6PrefixDelegation\0"
448 "TrafficControlQueueingDiscipline\0"
454 "DeficitRoundRobinScheduler\0"
455 "DeficitRoundRobinSchedulerClass\0"
456 "EnhancedTransmissionSelection\0"
458 "FairQueueingControlledDelay\0"
460 "GenericRandomEarlyDetection\0"
461 "HeavyHitterFilter\0"
462 "HierarchyTokenBucket\0"
463 "HierarchyTokenBucketClass\0"
469 "QuickFairQueueing\0"
470 "QuickFairQueueingClass\0"
471 "StochasticFairBlue\0"
472 "StochasticFairnessQueueing\0"
473 "TokenBucketFilter\0"
474 "TrivialLinkEqualizer\0",
475 config_item_perf_lookup
, network_network_gperf_lookup
,
478 &network
->timestamp
);
482 r
= network_add_ipv4ll_route(network
);
484 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
486 r
= network_add_default_route_on_device(network
);
488 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
491 if (network_verify(network
) < 0)
492 /* Ignore .network files that do not match the conditions. */
495 r
= ordered_hashmap_ensure_put(networks
, &string_hash_ops
, network
->name
, network
);
503 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
504 _cleanup_strv_free_
char **files
= NULL
;
510 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
512 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
514 return log_error_errno(r
, "Failed to enumerate network files: %m");
516 STRV_FOREACH(f
, files
) {
517 r
= network_load_one(manager
, networks
, *f
);
519 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
525 int network_reload(Manager
*manager
) {
526 OrderedHashmap
*new_networks
= NULL
;
532 r
= network_load(manager
, &new_networks
);
536 ORDERED_HASHMAP_FOREACH(n
, new_networks
) {
537 r
= network_get_by_name(manager
, n
->name
, &old
);
539 continue; /* The .network file is new. */
541 if (n
->timestamp
!= old
->timestamp
)
542 continue; /* The .network file is modified. */
544 if (!streq(n
->filename
, old
->filename
))
547 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
555 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
556 manager
->networks
= new_networks
;
561 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
566 static Network
*network_free(Network
*network
) {
570 free(network
->filename
);
572 net_match_clear(&network
->match
);
573 condition_free_list(network
->conditions
);
575 free(network
->dhcp_server_relay_agent_circuit_id
);
576 free(network
->dhcp_server_relay_agent_remote_id
);
578 free(network
->description
);
579 free(network
->dhcp_vendor_class_identifier
);
580 free(network
->dhcp_mudurl
);
581 strv_free(network
->dhcp_user_class
);
582 free(network
->dhcp_hostname
);
583 free(network
->dhcp_label
);
584 set_free(network
->dhcp_deny_listed_ip
);
585 set_free(network
->dhcp_allow_listed_ip
);
586 set_free(network
->dhcp_request_options
);
587 set_free(network
->dhcp6_request_options
);
589 free(network
->dhcp6_mudurl
);
590 strv_free(network
->dhcp6_user_class
);
591 strv_free(network
->dhcp6_vendor_class
);
593 strv_free(network
->ntp
);
594 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
595 in_addr_full_free(network
->dns
[i
]);
597 ordered_set_free(network
->search_domains
);
598 ordered_set_free(network
->route_domains
);
599 strv_free(network
->bind_carrier
);
601 ordered_set_free(network
->router_search_domains
);
602 free(network
->router_dns
);
603 set_free_free(network
->ndisc_deny_listed_router
);
604 set_free_free(network
->ndisc_allow_listed_router
);
605 set_free_free(network
->ndisc_deny_listed_prefix
);
606 set_free_free(network
->ndisc_allow_listed_prefix
);
607 set_free_free(network
->ndisc_deny_listed_route_prefix
);
608 set_free_free(network
->ndisc_allow_listed_route_prefix
);
610 free(network
->batadv_name
);
611 free(network
->bridge_name
);
612 free(network
->bond_name
);
613 free(network
->vrf_name
);
614 hashmap_free_free_key(network
->stacked_netdev_names
);
615 netdev_unref(network
->bridge
);
616 netdev_unref(network
->bond
);
617 netdev_unref(network
->vrf
);
618 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
620 set_free_free(network
->ipv6_proxy_ndp_addresses
);
621 ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
622 hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
623 hashmap_free_with_destructor(network
->nexthops_by_section
, nexthop_free
);
624 hashmap_free_with_destructor(network
->bridge_fdb_entries_by_section
, bridge_fdb_free
);
625 hashmap_free_with_destructor(network
->bridge_mdb_entries_by_section
, bridge_mdb_free
);
626 hashmap_free_with_destructor(network
->neighbors_by_section
, neighbor_free
);
627 hashmap_free_with_destructor(network
->address_labels_by_section
, address_label_free
);
628 hashmap_free_with_destructor(network
->prefixes_by_section
, prefix_free
);
629 hashmap_free_with_destructor(network
->route_prefixes_by_section
, route_prefix_free
);
630 hashmap_free_with_destructor(network
->rules_by_section
, routing_policy_rule_free
);
631 hashmap_free_with_destructor(network
->dhcp_static_leases_by_section
, dhcp_static_lease_free
);
632 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
633 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
637 free(network
->dhcp_server_timezone
);
638 free(network
->dhcp_server_uplink_name
);
639 free(network
->router_uplink_name
);
641 for (sd_dhcp_lease_server_type_t t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
642 free(network
->dhcp_server_emit
[t
].addresses
);
644 set_free_free(network
->dnssec_negative_trust_anchors
);
646 free(network
->lldp_mud
);
648 ordered_hashmap_free(network
->dhcp_client_send_options
);
649 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
650 ordered_hashmap_free(network
->dhcp_server_send_options
);
651 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
652 ordered_set_free(network
->ipv6_tokens
);
653 ordered_hashmap_free(network
->dhcp6_client_send_options
);
654 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
656 return mfree(network
);
659 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
661 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
668 network
= ordered_hashmap_get(manager
->networks
, name
);
677 bool network_has_static_ipv6_configurations(Network
*network
) {
686 ORDERED_HASHMAP_FOREACH(address
, network
->addresses_by_section
)
687 if (address
->family
== AF_INET6
)
690 HASHMAP_FOREACH(route
, network
->routes_by_section
)
691 if (route
->family
== AF_INET6
)
694 HASHMAP_FOREACH(fdb
, network
->bridge_fdb_entries_by_section
)
695 if (fdb
->family
== AF_INET6
)
698 HASHMAP_FOREACH(mdb
, network
->bridge_mdb_entries_by_section
)
699 if (mdb
->family
== AF_INET6
)
702 HASHMAP_FOREACH(neighbor
, network
->neighbors_by_section
)
703 if (neighbor
->family
== AF_INET6
)
706 if (!hashmap_isempty(network
->address_labels_by_section
))
709 if (!hashmap_isempty(network
->prefixes_by_section
))
712 if (!hashmap_isempty(network
->route_prefixes_by_section
))
718 int config_parse_stacked_netdev(
720 const char *filename
,
723 unsigned section_line
,
730 _cleanup_free_
char *name
= NULL
;
731 NetDevKind kind
= ltype
;
740 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
741 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
742 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
745 if (!ifname_valid(rvalue
)) {
746 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
747 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
751 name
= strdup(rvalue
);
755 r
= hashmap_ensure_put(h
, &string_hash_ops
, name
, INT_TO_PTR(kind
));
759 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
760 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
762 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
763 "NetDev '%s' specified twice, ignoring.", name
);
770 int config_parse_domains(
772 const char *filename
,
775 unsigned section_line
,
782 Network
*n
= userdata
;
790 if (isempty(rvalue
)) {
791 n
->search_domains
= ordered_set_free(n
->search_domains
);
792 n
->route_domains
= ordered_set_free(n
->route_domains
);
796 for (const char *p
= rvalue
;;) {
797 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
801 r
= extract_first_word(&p
, &w
, NULL
, 0);
805 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
806 "Failed to extract search or route domain, ignoring: %s", rvalue
);
812 is_route
= w
[0] == '~';
813 domain
= is_route
? w
+ 1 : w
;
815 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
816 /* If the root domain appears as is, or the special token "*" is found, we'll
817 * consider this as routing domain, unconditionally. */
819 domain
= "."; /* make sure we don't allow empty strings, thus write the root
822 r
= dns_name_normalize(domain
, 0, &normalized
);
824 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
825 "'%s' is not a valid domain name, ignoring.", domain
);
831 if (is_localhost(domain
)) {
832 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
833 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
839 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
840 r
= ordered_set_put_strdup(set
, domain
);
848 int config_parse_hostname(
850 const char *filename
,
853 unsigned section_line
,
860 char **hostname
= data
;
868 if (isempty(rvalue
)) {
869 *hostname
= mfree(*hostname
);
873 if (!hostname_is_valid(rvalue
, 0)) {
874 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
875 "Hostname is not valid, ignoring assignment: %s", rvalue
);
879 r
= dns_name_is_valid(rvalue
);
881 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
882 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
886 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
887 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
891 return free_and_strdup_warn(hostname
, rvalue
);
894 int config_parse_timezone(
896 const char *filename
,
899 unsigned section_line
,
914 if (isempty(rvalue
)) {
919 r
= verify_timezone(rvalue
, LOG_WARNING
);
921 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
922 "Timezone is not valid, ignoring assignment: %s", rvalue
);
926 return free_and_strdup_warn(tz
, rvalue
);
929 int config_parse_dns(
931 const char *filename
,
934 unsigned section_line
,
941 Network
*n
= userdata
;
949 if (isempty(rvalue
)) {
950 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
951 in_addr_full_free(n
->dns
[i
]);
952 n
->dns
= mfree(n
->dns
);
957 for (const char *p
= rvalue
;;) {
958 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
959 _cleanup_free_
char *w
= NULL
;
960 struct in_addr_full
**m
;
962 r
= extract_first_word(&p
, &w
, NULL
, 0);
966 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
967 "Invalid syntax, ignoring: %s", rvalue
);
973 r
= in_addr_full_new_from_string(w
, &dns
);
975 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
976 "Failed to parse dns server address, ignoring: %s", w
);
980 if (IN_SET(dns
->port
, 53, 853))
983 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
987 m
[n
->n_dns
++] = TAKE_PTR(dns
);
992 int config_parse_dnssec_negative_trust_anchors(
994 const char *filename
,
997 unsigned section_line
,
1012 if (isempty(rvalue
)) {
1013 *nta
= set_free_free(*nta
);
1017 for (const char *p
= rvalue
;;) {
1018 _cleanup_free_
char *w
= NULL
;
1020 r
= extract_first_word(&p
, &w
, NULL
, 0);
1024 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1025 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1031 r
= dns_name_is_valid(w
);
1033 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1034 "%s is not a valid domain name, ignoring.", w
);
1038 r
= set_ensure_consume(nta
, &dns_name_hash_ops
, TAKE_PTR(w
));
1044 int config_parse_ntp(
1046 const char *filename
,
1048 const char *section
,
1049 unsigned section_line
,
1064 if (isempty(rvalue
)) {
1069 for (const char *p
= rvalue
;;) {
1070 _cleanup_free_
char *w
= NULL
;
1072 r
= extract_first_word(&p
, &w
, NULL
, 0);
1076 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1077 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1083 r
= dns_name_is_valid_or_address(w
);
1085 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1086 "%s is not a valid domain name or IP address, ignoring.", w
);
1090 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1091 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1092 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1093 MAX_NTP_SERVERS
, w
);
1097 r
= strv_consume(l
, TAKE_PTR(w
));
1103 int config_parse_required_for_online(
1105 const char *filename
,
1107 const char *section
,
1108 unsigned section_line
,
1115 Network
*network
= userdata
;
1116 LinkOperationalStateRange range
;
1117 bool required
= true;
1125 if (isempty(rvalue
)) {
1126 network
->required_for_online
= -1;
1127 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1131 r
= parse_operational_state_range(rvalue
, &range
);
1133 r
= parse_boolean(rvalue
);
1135 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1136 "Failed to parse %s= setting, ignoring assignment: %s",
1142 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1145 network
->required_for_online
= required
;
1146 network
->required_operstate_for_online
= range
;
1151 int config_parse_link_group(
1153 const char *filename
,
1155 const char *section
,
1156 unsigned section_line
,
1163 Network
*network
= userdata
;
1171 if (isempty(rvalue
)) {
1173 network
->group_set
= false;
1177 r
= safe_atou32(rvalue
, &network
->group
);
1179 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1180 "Failed to parse Group=, ignoring assignment: %s", rvalue
);
1184 network
->group_set
= true;
1189 int config_parse_uplink(
1191 const char *filename
,
1193 const char *section
,
1194 unsigned section_line
,
1201 Network
*network
= userdata
;
1210 if (streq(section
, "DHCPServer")) {
1211 index
= &network
->dhcp_server_uplink_index
;
1212 name
= &network
->dhcp_server_uplink_name
;
1213 } else if (streq(section
, "IPv6SendRA")) {
1214 index
= &network
->router_uplink_index
;
1215 name
= &network
->router_uplink_name
;
1217 assert_not_reached();
1219 if (isempty(rvalue
) || streq(rvalue
, ":auto")) {
1220 *index
= UPLINK_INDEX_AUTO
;
1221 *name
= mfree(*name
);
1225 if (streq(rvalue
, ":none")) {
1226 *index
= UPLINK_INDEX_NONE
;
1227 *name
= mfree(*name
);
1231 r
= parse_ifindex(rvalue
);
1234 *name
= mfree(*name
);
1238 if (!ifname_valid_full(rvalue
, IFNAME_VALID_ALTERNATIVE
)) {
1239 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1240 "Invalid interface name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
1244 /* The interface name will be resolved later. */
1245 r
= free_and_strdup_warn(name
, rvalue
);
1249 /* Note, if uplink_name is set, then uplink_index will be ignored. So, the below does not mean
1250 * an uplink interface will be selected automatically. */
1251 *index
= UPLINK_INDEX_AUTO
;
1255 DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online
, link_required_address_family
, AddressFamily
,
1256 "Failed to parse RequiredFamilyForOnline= setting");
1258 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1259 "Failed to parse KeepConfiguration= setting");
1261 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1262 [KEEP_CONFIGURATION_NO
] = "no",
1263 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1264 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1265 [KEEP_CONFIGURATION_STATIC
] = "static",
1266 [KEEP_CONFIGURATION_YES
] = "yes",
1269 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1271 static const char* const ipv6_link_local_address_gen_mode_table
[_IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX
] = {
1272 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64
] = "eui64",
1273 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
] = "none",
1274 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
] = "stable-privacy",
1275 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM
] = "random",
1278 DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode
, IPv6LinkLocalAddressGenMode
);
1279 DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_link_local_address_gen_mode
, ipv6_link_local_address_gen_mode
, IPv6LinkLocalAddressGenMode
, "Failed to parse IPv6 link local address generation mode");
1281 static const char* const activation_policy_table
[_ACTIVATION_POLICY_MAX
] = {
1282 [ACTIVATION_POLICY_UP
] = "up",
1283 [ACTIVATION_POLICY_ALWAYS_UP
] = "always-up",
1284 [ACTIVATION_POLICY_MANUAL
] = "manual",
1285 [ACTIVATION_POLICY_ALWAYS_DOWN
] = "always-down",
1286 [ACTIVATION_POLICY_DOWN
] = "down",
1287 [ACTIVATION_POLICY_BOUND
] = "bound",
1290 DEFINE_STRING_TABLE_LOOKUP(activation_policy
, ActivationPolicy
);
1291 DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy
, activation_policy
, ActivationPolicy
, "Failed to parse activation policy");