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-dhcp-common.h"
19 #include "networkd-dhcp-server.h"
20 #include "networkd-fdb.h"
21 #include "networkd-manager.h"
22 #include "networkd-mdb.h"
23 #include "networkd-ndisc.h"
24 #include "networkd-neighbor.h"
25 #include "networkd-network.h"
26 #include "networkd-nexthop.h"
27 #include "networkd-radv.h"
28 #include "networkd-routing-policy-rule.h"
29 #include "networkd-sriov.h"
30 #include "parse-util.h"
31 #include "path-lookup.h"
33 #include "socket-util.h"
34 #include "stat-util.h"
35 #include "string-table.h"
36 #include "string-util.h"
41 /* Let's assume that anything above this number is a user misconfiguration. */
42 #define MAX_NTP_SERVERS 128
44 /* Set defaults following RFC7844 */
45 void network_apply_anonymize_if_set(Network
*network
) {
46 if (!network
->dhcp_anonymize
)
49 SHOULD NOT send the Host Name option */
50 network
->dhcp_send_hostname
= false;
51 /* RFC7844 section 3.:
52 MAY contain the Client Identifier option
54 clients MUST use client identifiers based solely
55 on the link-layer address */
56 /* NOTE: Using MAC, as it does not reveal extra information,
57 * and some servers might not answer if this option is not sent */
58 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
60 SHOULD NOT use the Vendor Class Identifier option */
61 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
62 /* RFC7844 section 3.6.:
63 The client intending to protect its privacy SHOULD only request a
64 minimal number of options in the PRL and SHOULD also randomly shuffle
65 the ordering of option codes in the PRL. If this random ordering
66 cannot be implemented, the client MAY order the option codes in the
67 PRL by option code number (lowest to highest).
69 /* NOTE: dhcp_use_mtu is false by default,
70 * though it was not initiallized to any value in network_load_one.
71 * Maybe there should be another var called *send*?
72 * (to use the MTU sent by the server but to do not send
73 * the option in the PRL). */
74 network
->dhcp_use_mtu
= false;
75 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
76 * but this is needed to use them. */
77 network
->dhcp_use_routes
= true;
78 /* RFC7844 section 3.6.
79 * same comments as previous option */
80 network
->dhcp_use_timezone
= false;
83 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
84 const char *kind_string
;
88 /* For test-networkd-conf, the check must be earlier than the assertions. */
93 assert(network
->manager
);
94 assert(network
->filename
);
97 if (kind
== _NETDEV_KIND_TUNNEL
)
98 kind_string
= "tunnel";
100 kind_string
= netdev_kind_to_string(kind
);
102 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
103 "%s: Invalid NetDev kind of %s, ignoring assignment.",
104 network
->filename
, name
);
107 r
= netdev_get(network
->manager
, name
, &netdev
);
109 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
110 network
->filename
, name
);
112 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
119 NETDEV_KIND_IP6GRETAP
,
123 NETDEV_KIND_ERSPAN
)))
124 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
125 "%s: NetDev %s is not a %s, ignoring assignment",
126 network
->filename
, name
, kind_string
);
128 *ret_netdev
= netdev_ref(netdev
);
132 static int network_resolve_stacked_netdevs(Network
*network
) {
138 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
) {
139 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
141 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
145 r
= hashmap_ensure_put(&network
->stacked_netdevs
, &string_hash_ops
, netdev
->ifname
, netdev
);
149 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
150 network
->filename
, (const char *) name
);
158 int network_verify(Network
*network
) {
160 assert(network
->filename
);
162 if (net_match_is_empty(&network
->match
) && !network
->conditions
)
163 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
164 "%s: No valid settings found in the [Match] section, ignoring file. "
165 "To match all interfaces, add Name=* in the [Match] section.",
168 /* skip out early if configuration does not match the environment */
169 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
170 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
171 "%s: Conditions in the file do not match the system environment, skipping.",
174 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
175 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
176 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
177 (void) network_resolve_stacked_netdevs(network
);
179 /* Free unnecessary entries. */
180 network
->bond_name
= mfree(network
->bond_name
);
181 network
->bridge_name
= mfree(network
->bridge_name
);
182 network
->vrf_name
= mfree(network
->vrf_name
);
183 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
186 /* Bonding slave does not support addressing. */
187 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
188 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
190 network
->link_local
= ADDRESS_FAMILY_NO
;
192 if (network
->dhcp_server
) {
193 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
195 network
->dhcp_server
= false;
197 if (!ordered_hashmap_isempty(network
->addresses_by_section
))
198 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
200 if (!hashmap_isempty(network
->routes_by_section
))
201 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
204 network
->addresses_by_section
= ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
205 network
->routes_by_section
= hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
208 if (network
->link_local
< 0)
209 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
211 /* IPMasquerade implies IPForward */
212 network
->ip_forward
|= network
->ip_masquerade
;
214 network_adjust_ipv6_accept_ra(network
);
215 network_adjust_dhcp(network
);
216 network_adjust_radv(network
);
218 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
219 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
220 "Disabling UseMTU=.", network
->filename
);
221 network
->dhcp_use_mtu
= false;
224 if (network
->dhcp_use_gateway
< 0)
225 network
->dhcp_use_gateway
= network
->dhcp_use_routes
;
227 if (network
->dhcp_critical
>= 0) {
228 if (network
->keep_configuration
>= 0)
229 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
230 "Ignoring CriticalConnection=.", network
->filename
);
231 else if (network
->dhcp_critical
)
232 /* CriticalConnection=yes also preserve foreign static configurations. */
233 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
235 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
238 if (!strv_isempty(network
->bind_carrier
)) {
239 if (!IN_SET(network
->activation_policy
, _ACTIVATION_POLICY_INVALID
, ACTIVATION_POLICY_BOUND
))
240 log_warning("%s: ActivationPolicy=bound is required with BindCarrier=. "
241 "Setting ActivationPolicy=bound.", network
->filename
);
242 network
->activation_policy
= ACTIVATION_POLICY_BOUND
;
243 } else if (network
->activation_policy
== ACTIVATION_POLICY_BOUND
) {
244 log_warning("%s: ActivationPolicy=bound requires BindCarrier=. "
245 "Ignoring ActivationPolicy=bound.", network
->filename
);
246 network
->activation_policy
= ACTIVATION_POLICY_UP
;
249 if (network
->activation_policy
== _ACTIVATION_POLICY_INVALID
)
250 network
->activation_policy
= ACTIVATION_POLICY_UP
;
252 if (network
->activation_policy
== ACTIVATION_POLICY_ALWAYS_UP
) {
253 if (network
->ignore_carrier_loss
== false)
254 log_warning("%s: IgnoreCarrierLoss=false conflicts with ActivationPolicy=always-up. "
255 "Setting IgnoreCarrierLoss=true.", network
->filename
);
256 network
->ignore_carrier_loss
= true;
259 if (network
->ignore_carrier_loss
< 0)
260 network
->ignore_carrier_loss
= network
->configure_without_carrier
;
262 if (network
->keep_configuration
< 0)
263 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
265 if (network
->ipv6_proxy_ndp
== 0 && !set_isempty(network
->ipv6_proxy_ndp_addresses
)) {
266 log_warning("%s: IPv6ProxyNDP= is disabled. Ignoring IPv6ProxyNDPAddress=.", network
->filename
);
267 network
->ipv6_proxy_ndp_addresses
= set_free_free(network
->ipv6_proxy_ndp_addresses
);
270 network_drop_invalid_addresses(network
);
271 network_drop_invalid_routes(network
);
272 network_drop_invalid_nexthops(network
);
273 network_drop_invalid_fdb_entries(network
);
274 network_drop_invalid_mdb_entries(network
);
275 network_drop_invalid_neighbors(network
);
276 network_drop_invalid_address_labels(network
);
277 network_drop_invalid_prefixes(network
);
278 network_drop_invalid_route_prefixes(network
);
279 network_drop_invalid_routing_policy_rules(network
);
280 network_drop_invalid_traffic_control(network
);
281 network_drop_invalid_sr_iov(network
);
286 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
287 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
288 _cleanup_(network_unrefp
) Network
*network
= NULL
;
289 _cleanup_fclose_
FILE *file
= NULL
;
290 const char *dropin_dirname
;
297 file
= fopen(filename
, "re");
305 if (null_or_empty_fd(fileno(file
))) {
306 log_debug("Skipping empty file: %s", filename
);
310 fname
= strdup(filename
);
314 name
= strdup(basename(filename
));
318 d
= strrchr(name
, '.');
324 dropin_dirname
= strjoina(name
, ".network.d");
326 network
= new(Network
, 1);
330 *network
= (Network
) {
331 .filename
= TAKE_PTR(fname
),
332 .name
= TAKE_PTR(name
),
337 .required_for_online
= true,
338 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
339 .activation_policy
= _ACTIVATION_POLICY_INVALID
,
345 .configure_without_carrier
= false,
346 .ignore_carrier_loss
= -1,
347 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
349 .dhcp
= ADDRESS_FAMILY_NO
,
350 .duid
.type
= _DUID_TYPE_INVALID
,
352 .dhcp_use_ntp
= true,
353 .dhcp_use_sip
= true,
354 .dhcp_use_dns
= true,
355 .dhcp_use_hostname
= true,
356 .dhcp_use_routes
= true,
357 .dhcp_use_gateway
= -1,
358 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
359 .dhcp_send_hostname
= true,
360 .dhcp_send_release
= true,
361 /* To enable/disable RFC7844 Anonymity Profiles */
362 .dhcp_anonymize
= false,
363 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
364 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
365 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
366 .dhcp_route_table
= RT_TABLE_MAIN
,
367 .dhcp_route_table_set
= false,
368 /* NOTE: from man: UseMTU=... Defaults to false*/
369 .dhcp_use_mtu
= false,
370 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
371 .dhcp_use_timezone
= false,
372 .dhcp_ip_service_type
= -1,
374 .dhcp6_use_address
= true,
375 .dhcp6_use_dns
= true,
376 .dhcp6_use_fqdn
= true,
377 .dhcp6_use_ntp
= true,
378 .dhcp6_rapid_commit
= true,
379 .dhcp6_route_metric
= DHCP_ROUTE_METRIC
,
382 .dhcp6_pd_announce
= true,
383 .dhcp6_pd_assign
= true,
384 .dhcp6_pd_manage_temporary_address
= true,
385 .dhcp6_pd_subnet_id
= -1,
387 .dhcp_server_emit
[SD_DHCP_LEASE_DNS
].emit
= true,
388 .dhcp_server_emit
[SD_DHCP_LEASE_NTP
].emit
= true,
389 .dhcp_server_emit
[SD_DHCP_LEASE_SIP
].emit
= true,
391 .dhcp_server_emit_router
= true,
392 .dhcp_server_emit_timezone
= true,
394 .router_lifetime_usec
= 30 * USEC_PER_MINUTE
,
395 .router_emit_dns
= true,
396 .router_emit_domains
= true,
401 .allow_port_to_be_root
= -1,
403 .multicast_flood
= -1,
404 .multicast_to_unicast
= -1,
405 .neighbor_suppression
= -1,
407 .bridge_proxy_arp
= -1,
408 .bridge_proxy_arp_wifi
= -1,
409 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
410 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
412 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
414 .dns_default_route
= -1,
415 .llmnr
= RESOLVE_SUPPORT_YES
,
416 .mdns
= RESOLVE_SUPPORT_NO
,
417 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
418 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
420 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
421 .link_local
= _ADDRESS_FAMILY_INVALID
,
422 .ipv6ll_address_gen_mode
= _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID
,
424 .ipv4_accept_local
= -1,
425 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
426 .ipv6_accept_ra
= -1,
427 .ipv6_dad_transmits
= -1,
428 .ipv6_hop_limit
= -1,
429 .ipv6_proxy_ndp
= -1,
432 .ipv6_accept_ra_use_dns
= true,
433 .ipv6_accept_ra_use_autonomous_prefix
= true,
434 .ipv6_accept_ra_use_onlink_prefix
= true,
435 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
436 .ipv6_accept_ra_route_table_set
= false,
437 .ipv6_accept_ra_start_dhcp6_client
= IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
,
439 .can_triple_sampling
= -1,
440 .can_berr_reporting
= -1,
441 .can_termination
= -1,
442 .can_listen_only
= -1,
447 r
= config_parse_many(
448 filename
, NETWORK_DIRS
, dropin_dirname
,
456 "RoutingPolicyRule\0"
459 "DHCP\0" /* compat */
462 "DHCPv6PrefixDelegation\0"
465 "IPv6NDPProxyAddress\0"
471 "IPv6PrefixDelegation\0"
475 "TrafficControlQueueingDiscipline\0"
481 "DeficitRoundRobinScheduler\0"
482 "DeficitRoundRobinSchedulerClass\0"
483 "EnhancedTransmissionSelection\0"
485 "FairQueueingControlledDelay\0"
487 "GenericRandomEarlyDetection\0"
488 "HeavyHitterFilter\0"
489 "HierarchyTokenBucket\0"
490 "HierarchyTokenBucketClass\0"
496 "QuickFairQueueing\0"
497 "QuickFairQueueingClass\0"
498 "StochasticFairBlue\0"
499 "StochasticFairnessQueueing\0"
500 "TokenBucketFilter\0"
501 "TrivialLinkEqualizer\0",
502 config_item_perf_lookup
, network_network_gperf_lookup
,
505 &network
->timestamp
);
509 network_apply_anonymize_if_set(network
);
511 r
= network_add_ipv4ll_route(network
);
513 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
515 r
= network_add_default_route_on_device(network
);
517 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
520 if (network_verify(network
) < 0)
521 /* Ignore .network files that do not match the conditions. */
524 r
= ordered_hashmap_ensure_put(networks
, &string_hash_ops
, network
->name
, network
);
532 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
533 _cleanup_strv_free_
char **files
= NULL
;
539 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
541 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
543 return log_error_errno(r
, "Failed to enumerate network files: %m");
545 STRV_FOREACH(f
, files
) {
546 r
= network_load_one(manager
, networks
, *f
);
548 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
554 int network_reload(Manager
*manager
) {
555 OrderedHashmap
*new_networks
= NULL
;
561 r
= network_load(manager
, &new_networks
);
565 ORDERED_HASHMAP_FOREACH(n
, new_networks
) {
566 r
= network_get_by_name(manager
, n
->name
, &old
);
568 continue; /* The .network file is new. */
570 if (n
->timestamp
!= old
->timestamp
)
571 continue; /* The .network file is modified. */
573 if (!streq(n
->filename
, old
->filename
))
576 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
584 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
585 manager
->networks
= new_networks
;
590 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
595 static Network
*network_free(Network
*network
) {
599 free(network
->filename
);
601 net_match_clear(&network
->match
);
602 condition_free_list(network
->conditions
);
604 free(network
->description
);
605 free(network
->dhcp_vendor_class_identifier
);
606 free(network
->dhcp_mudurl
);
607 strv_free(network
->dhcp_user_class
);
608 free(network
->dhcp_hostname
);
609 set_free(network
->dhcp_deny_listed_ip
);
610 set_free(network
->dhcp_allow_listed_ip
);
611 set_free(network
->dhcp_request_options
);
612 set_free(network
->dhcp6_request_options
);
614 free(network
->dhcp6_mudurl
);
615 strv_free(network
->dhcp6_user_class
);
616 strv_free(network
->dhcp6_vendor_class
);
618 strv_free(network
->ntp
);
619 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
620 in_addr_full_free(network
->dns
[i
]);
622 ordered_set_free(network
->search_domains
);
623 ordered_set_free(network
->route_domains
);
624 strv_free(network
->bind_carrier
);
626 ordered_set_free(network
->router_search_domains
);
627 free(network
->router_dns
);
628 set_free_free(network
->ndisc_deny_listed_router
);
629 set_free_free(network
->ndisc_allow_listed_router
);
630 set_free_free(network
->ndisc_deny_listed_prefix
);
631 set_free_free(network
->ndisc_allow_listed_prefix
);
632 set_free_free(network
->ndisc_deny_listed_route_prefix
);
633 set_free_free(network
->ndisc_allow_listed_route_prefix
);
635 free(network
->bridge_name
);
636 free(network
->bond_name
);
637 free(network
->vrf_name
);
638 hashmap_free_free_key(network
->stacked_netdev_names
);
639 netdev_unref(network
->bridge
);
640 netdev_unref(network
->bond
);
641 netdev_unref(network
->vrf
);
642 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
644 set_free_free(network
->ipv6_proxy_ndp_addresses
);
645 ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
646 hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
647 hashmap_free_with_destructor(network
->nexthops_by_section
, nexthop_free
);
648 hashmap_free_with_destructor(network
->fdb_entries_by_section
, fdb_entry_free
);
649 hashmap_free_with_destructor(network
->mdb_entries_by_section
, mdb_entry_free
);
650 hashmap_free_with_destructor(network
->neighbors_by_section
, neighbor_free
);
651 hashmap_free_with_destructor(network
->address_labels_by_section
, address_label_free
);
652 hashmap_free_with_destructor(network
->prefixes_by_section
, prefix_free
);
653 hashmap_free_with_destructor(network
->route_prefixes_by_section
, route_prefix_free
);
654 hashmap_free_with_destructor(network
->rules_by_section
, routing_policy_rule_free
);
655 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
656 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
658 if (network
->manager
&&
659 network
->manager
->duids_requesting_uuid
)
660 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
664 free(network
->dhcp_server_timezone
);
666 for (sd_dhcp_lease_server_type t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
667 free(network
->dhcp_server_emit
[t
].addresses
);
669 set_free_free(network
->dnssec_negative_trust_anchors
);
671 free(network
->lldp_mud
);
673 ordered_hashmap_free(network
->dhcp_client_send_options
);
674 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
675 ordered_hashmap_free(network
->dhcp_server_send_options
);
676 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
677 ordered_set_free(network
->ipv6_tokens
);
678 ordered_hashmap_free(network
->dhcp6_client_send_options
);
679 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
681 return mfree(network
);
684 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
686 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
693 network
= ordered_hashmap_get(manager
->networks
, name
);
702 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
703 const char *ifname
, char * const *alternative_names
, const char *driver
,
704 const struct ether_addr
*mac
, const struct ether_addr
*permanent_mac
,
705 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
712 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
)
713 if (net_match_config(&network
->match
, device
, mac
, permanent_mac
, driver
, iftype
,
714 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
715 if (network
->match
.ifname
&& device
) {
717 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
719 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
720 (void) safe_atou8(attr
, &name_assign_type
);
722 if (name_assign_type
== NET_NAME_ENUM
)
723 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
724 ifname
, network
->filename
);
726 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
728 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
739 bool network_has_static_ipv6_configurations(Network
*network
) {
748 ORDERED_HASHMAP_FOREACH(address
, network
->addresses_by_section
)
749 if (address
->family
== AF_INET6
)
752 HASHMAP_FOREACH(route
, network
->routes_by_section
)
753 if (route
->family
== AF_INET6
)
756 HASHMAP_FOREACH(fdb
, network
->fdb_entries_by_section
)
757 if (fdb
->family
== AF_INET6
)
760 HASHMAP_FOREACH(mdb
, network
->mdb_entries_by_section
)
761 if (mdb
->family
== AF_INET6
)
764 HASHMAP_FOREACH(neighbor
, network
->neighbors_by_section
)
765 if (neighbor
->family
== AF_INET6
)
768 if (!hashmap_isempty(network
->address_labels_by_section
))
771 if (!hashmap_isempty(network
->prefixes_by_section
))
774 if (!hashmap_isempty(network
->route_prefixes_by_section
))
780 int config_parse_stacked_netdev(const char *unit
,
781 const char *filename
,
784 unsigned section_line
,
790 _cleanup_free_
char *name
= NULL
;
791 NetDevKind kind
= ltype
;
800 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
801 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
802 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
805 if (!ifname_valid(rvalue
)) {
806 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
807 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
811 name
= strdup(rvalue
);
815 r
= hashmap_ensure_put(h
, &string_hash_ops
, name
, INT_TO_PTR(kind
));
819 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
820 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
822 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
823 "NetDev '%s' specified twice, ignoring.", name
);
830 int config_parse_domains(
832 const char *filename
,
835 unsigned section_line
,
849 if (isempty(rvalue
)) {
850 n
->search_domains
= ordered_set_free(n
->search_domains
);
851 n
->route_domains
= ordered_set_free(n
->route_domains
);
855 for (const char *p
= rvalue
;;) {
856 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
860 r
= extract_first_word(&p
, &w
, NULL
, 0);
864 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
865 "Failed to extract search or route domain, ignoring: %s", rvalue
);
871 is_route
= w
[0] == '~';
872 domain
= is_route
? w
+ 1 : w
;
874 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
875 /* If the root domain appears as is, or the special token "*" is found, we'll
876 * consider this as routing domain, unconditionally. */
878 domain
= "."; /* make sure we don't allow empty strings, thus write the root
881 r
= dns_name_normalize(domain
, 0, &normalized
);
883 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
884 "'%s' is not a valid domain name, ignoring.", domain
);
890 if (is_localhost(domain
)) {
891 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
892 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
898 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
899 r
= ordered_set_ensure_allocated(set
, &string_hash_ops_free
);
903 r
= ordered_set_put_strdup(*set
, domain
);
909 int config_parse_hostname(
911 const char *filename
,
914 unsigned section_line
,
921 _cleanup_free_
char *hn
= NULL
;
922 char **hostname
= data
;
929 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
933 if (!hostname_is_valid(hn
, 0)) {
934 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
935 "Hostname is not valid, ignoring assignment: %s", rvalue
);
939 r
= dns_name_is_valid(hn
);
941 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
942 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
946 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
947 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
951 return free_and_replace(*hostname
, hn
);
954 int config_parse_timezone(
956 const char *filename
,
959 unsigned section_line
,
966 _cleanup_free_
char *tz
= NULL
;
974 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
978 if (!timezone_is_valid(tz
, LOG_WARNING
)) {
979 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
980 "Timezone is not valid, ignoring assignment: %s", rvalue
);
984 return free_and_replace(*datap
, tz
);
987 int config_parse_dns(
989 const char *filename
,
992 unsigned section_line
,
999 Network
*n
= userdata
;
1006 if (isempty(rvalue
)) {
1007 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
1008 in_addr_full_free(n
->dns
[i
]);
1009 n
->dns
= mfree(n
->dns
);
1014 for (const char *p
= rvalue
;;) {
1015 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
1016 _cleanup_free_
char *w
= NULL
;
1017 struct in_addr_full
**m
;
1019 r
= extract_first_word(&p
, &w
, NULL
, 0);
1023 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1024 "Invalid syntax, ignoring: %s", rvalue
);
1030 r
= in_addr_full_new_from_string(w
, &dns
);
1032 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1033 "Failed to parse dns server address, ignoring: %s", w
);
1037 if (IN_SET(dns
->port
, 53, 853))
1040 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
1044 m
[n
->n_dns
++] = TAKE_PTR(dns
);
1049 int config_parse_dnssec_negative_trust_anchors(
1051 const char *filename
,
1053 const char *section
,
1054 unsigned section_line
,
1068 if (isempty(rvalue
)) {
1069 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1073 for (const char *p
= rvalue
;;) {
1074 _cleanup_free_
char *w
= NULL
;
1076 r
= extract_first_word(&p
, &w
, NULL
, 0);
1080 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1081 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1087 r
= dns_name_is_valid(w
);
1089 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1090 "%s is not a valid domain name, ignoring.", w
);
1094 r
= set_ensure_consume(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
, TAKE_PTR(w
));
1100 int config_parse_ntp(
1102 const char *filename
,
1104 const char *section
,
1105 unsigned section_line
,
1119 if (isempty(rvalue
)) {
1124 for (const char *p
= rvalue
;;) {
1125 _cleanup_free_
char *w
= NULL
;
1127 r
= extract_first_word(&p
, &w
, NULL
, 0);
1131 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1132 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1138 r
= dns_name_is_valid_or_address(w
);
1140 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1141 "%s is not a valid domain name or IP address, ignoring.", w
);
1145 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1146 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1147 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1148 MAX_NTP_SERVERS
, w
);
1152 r
= strv_consume(l
, TAKE_PTR(w
));
1158 int config_parse_required_for_online(
1160 const char *filename
,
1162 const char *section
,
1163 unsigned section_line
,
1170 Network
*network
= data
;
1171 LinkOperationalStateRange range
;
1172 bool required
= true;
1175 if (isempty(rvalue
)) {
1176 network
->required_for_online
= true;
1177 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1181 r
= parse_operational_state_range(rvalue
, &range
);
1183 r
= parse_boolean(rvalue
);
1185 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1186 "Failed to parse %s= setting, ignoring assignment: %s",
1192 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1195 network
->required_for_online
= required
;
1196 network
->required_operstate_for_online
= range
;
1201 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1202 "Failed to parse KeepConfiguration= setting");
1204 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1205 [KEEP_CONFIGURATION_NO
] = "no",
1206 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1207 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1208 [KEEP_CONFIGURATION_STATIC
] = "static",
1209 [KEEP_CONFIGURATION_YES
] = "yes",
1212 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1214 static const char* const ipv6_link_local_address_gen_mode_table
[_IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX
] = {
1215 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64
] = "eui64",
1216 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
] = "none",
1217 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
] = "stable-privacy",
1218 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM
] = "random",
1221 DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode
, IPv6LinkLocalAddressGenMode
);
1222 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");
1224 static const char* const activation_policy_table
[_ACTIVATION_POLICY_MAX
] = {
1225 [ACTIVATION_POLICY_UP
] = "up",
1226 [ACTIVATION_POLICY_ALWAYS_UP
] = "always-up",
1227 [ACTIVATION_POLICY_MANUAL
] = "manual",
1228 [ACTIVATION_POLICY_ALWAYS_DOWN
] = "always-down",
1229 [ACTIVATION_POLICY_DOWN
] = "down",
1230 [ACTIVATION_POLICY_BOUND
] = "bound",
1233 DEFINE_STRING_TABLE_LOOKUP(activation_policy
, ActivationPolicy
);
1234 DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy
, activation_policy
, ActivationPolicy
, "Failed to parse activation policy");