1 /* SPDX-License-Identifier: LGPL-2.1+ */
4 #include <netinet/in.h>
5 #include <linux/netdevice.h>
7 #include "alloc-util.h"
8 #include "conf-files.h"
9 #include "conf-parser.h"
10 #include "dns-domain.h"
12 #include "hostname-util.h"
13 #include "in-addr-util.h"
14 #include "networkd-dhcp-server.h"
15 #include "network-internal.h"
16 #include "networkd-manager.h"
17 #include "networkd-network.h"
18 #include "parse-util.h"
20 #include "socket-util.h"
21 #include "stat-util.h"
22 #include "string-table.h"
23 #include "string-util.h"
27 /* Let's assume that anything above this number is a user misconfiguration. */
28 #define MAX_NTP_SERVERS 128
30 /* Set defaults following RFC7844 */
31 void network_apply_anonymize_if_set(Network
*network
) {
32 if (!network
->dhcp_anonymize
)
35 SHOULD NOT send the Host Name option */
36 network
->dhcp_send_hostname
= false;
37 /* RFC7844 section 3.:
38 MAY contain the Client Identifier option
40 clients MUST use client identifiers based solely
41 on the link-layer address */
42 /* NOTE: Using MAC, as it does not reveal extra information,
43 * and some servers might not answer if this option is not sent */
44 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
46 SHOULD NOT use the Vendor Class Identifier option */
47 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
48 /* RFC7844 section 3.6.:
49 The client intending to protect its privacy SHOULD only request a
50 minimal number of options in the PRL and SHOULD also randomly shuffle
51 the ordering of option codes in the PRL. If this random ordering
52 cannot be implemented, the client MAY order the option codes in the
53 PRL by option code number (lowest to highest).
55 /* NOTE: dhcp_use_mtu is false by default,
56 * though it was not initiallized to any value in network_load_one.
57 * Maybe there should be another var called *send*?
58 * (to use the MTU sent by the server but to do not send
59 * the option in the PRL). */
60 network
->dhcp_use_mtu
= false;
61 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
62 * but this is needed to use them. */
63 network
->dhcp_use_routes
= true;
64 /* RFC7844 section 3.6.
65 * same comments as previous option */
66 network
->dhcp_use_timezone
= false;
69 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
70 const char *kind_string
;
74 /* For test-networkd-conf, the check must be earlier than the assertions. */
79 assert(network
->manager
);
80 assert(network
->filename
);
83 if (kind
== _NETDEV_KIND_TUNNEL
)
84 kind_string
= "tunnel";
86 kind_string
= netdev_kind_to_string(kind
);
88 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
89 "%s: Invalid NetDev kind of %s, ignoring assignment.",
90 network
->filename
, name
);
93 r
= netdev_get(network
->manager
, name
, &netdev
);
95 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
96 network
->filename
, name
);
98 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
105 NETDEV_KIND_IP6GRETAP
,
109 NETDEV_KIND_ERSPAN
)))
110 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
111 "%s: NetDev %s is not a %s, ignoring assignment",
112 network
->filename
, name
, kind_string
);
114 *ret_netdev
= netdev_ref(netdev
);
118 static int network_resolve_stacked_netdevs(Network
*network
) {
125 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
126 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
128 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
132 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
136 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
138 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
139 network
->filename
, (const char *) name
);
147 int network_verify(Network
*network
) {
148 RoutePrefix
*route_prefix
, *route_prefix_next
;
149 RoutingPolicyRule
*rule
, *rule_next
;
150 Neighbor
*neighbor
, *neighbor_next
;
151 AddressLabel
*label
, *label_next
;
152 NextHop
*nexthop
, *nextnop_next
;
153 Address
*address
, *address_next
;
154 Prefix
*prefix
, *prefix_next
;
155 Route
*route
, *route_next
;
156 FdbEntry
*fdb
, *fdb_next
;
161 assert(network
->filename
);
163 if (set_isempty(network
->match_mac
) && set_isempty(network
->match_permanent_mac
) &&
164 strv_isempty(network
->match_path
) && strv_isempty(network
->match_driver
) &&
165 strv_isempty(network
->match_type
) && strv_isempty(network
->match_name
) &&
166 strv_isempty(network
->match_property
) && strv_isempty(network
->match_ssid
) && !network
->conditions
)
167 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
168 "%s: No valid settings found in the [Match] section, ignoring file. "
169 "To match all interfaces, add Name=* in the [Match] section.",
172 /* skip out early if configuration does not match the environment */
173 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
174 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
175 "%s: Conditions in the file do not match the system environment, skipping.",
178 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
179 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
180 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
181 (void) network_resolve_stacked_netdevs(network
);
183 /* Free unnecessary entries. */
184 network
->bond_name
= mfree(network
->bond_name
);
185 network
->bridge_name
= mfree(network
->bridge_name
);
186 network
->vrf_name
= mfree(network
->vrf_name
);
187 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
190 /* Bonding slave does not support addressing. */
191 if (network
->ipv6_accept_ra
> 0) {
192 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
194 network
->ipv6_accept_ra
= 0;
196 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
197 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
199 network
->link_local
= ADDRESS_FAMILY_NO
;
201 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
202 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
204 network
->dhcp
= ADDRESS_FAMILY_NO
;
206 if (network
->dhcp_server
) {
207 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
209 network
->dhcp_server
= false;
211 if (network
->n_static_addresses
> 0) {
212 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
214 while ((address
= network
->static_addresses
))
215 address_free(address
);
217 if (network
->n_static_routes
> 0) {
218 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
220 while ((route
= network
->static_routes
))
225 if (network
->link_local
< 0)
226 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
228 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
229 if (network
->ipv6_accept_ra
> 0) {
230 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
231 "Disabling IPv6AcceptRA=.", network
->filename
);
232 network
->ipv6_accept_ra
= false;
235 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
236 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
237 "Disabling DHCPv6 client.", network
->filename
);
238 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
241 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
242 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
243 "Disabling IPv6PrefixDelegation=.", network
->filename
);
244 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
248 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
249 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
250 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
251 "Disabling the fallback assignment.", network
->filename
);
252 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
255 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
256 network
->ipv6_accept_ra
= false;
258 /* IPMasquerade=yes implies IPForward=yes */
259 if (network
->ip_masquerade
)
260 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
262 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
263 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
264 "Disabling UseMTU=.", network
->filename
);
265 network
->dhcp_use_mtu
= false;
268 if (network
->dhcp_critical
>= 0) {
269 if (network
->keep_configuration
>= 0)
270 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
271 "Ignoring CriticalConnection=.", network
->filename
);
272 else if (network
->dhcp_critical
)
273 /* CriticalConnection=yes also preserve foreign static configurations. */
274 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
276 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
279 if (network
->keep_configuration
< 0)
280 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
282 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
283 if (address_section_verify(address
) < 0)
284 address_free(address
);
286 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
287 if (route_section_verify(route
, network
) < 0)
290 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
291 if (nexthop_section_verify(nexthop
) < 0)
292 nexthop_free(nexthop
);
294 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
295 if (section_is_invalid(fdb
->section
))
298 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
299 if (neighbor_section_verify(neighbor
) < 0)
300 neighbor_free(neighbor
);
302 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
303 if (section_is_invalid(label
->section
))
304 address_label_free(label
);
306 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
307 if (section_is_invalid(prefix
->section
))
310 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
311 if (section_is_invalid(route_prefix
->section
))
312 route_prefix_free(route_prefix
);
314 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
315 if (routing_policy_rule_section_verify(rule
) < 0)
316 routing_policy_rule_free(rule
);
318 bool has_root
= false, has_clsact
= false;
319 ORDERED_HASHMAP_FOREACH(qdisc
, network
->qdiscs_by_section
, i
)
320 if (qdisc_section_verify(qdisc
, &has_root
, &has_clsact
) < 0)
326 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
327 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
328 _cleanup_(network_unrefp
) Network
*network
= NULL
;
329 _cleanup_fclose_
FILE *file
= NULL
;
330 const char *dropin_dirname
;
337 file
= fopen(filename
, "re");
345 if (null_or_empty_fd(fileno(file
))) {
346 log_debug("Skipping empty file: %s", filename
);
350 fname
= strdup(filename
);
354 name
= strdup(basename(filename
));
358 d
= strrchr(name
, '.');
364 dropin_dirname
= strjoina(name
, ".network.d");
366 network
= new(Network
, 1);
370 *network
= (Network
) {
371 .filename
= TAKE_PTR(fname
),
372 .name
= TAKE_PTR(name
),
377 .required_for_online
= true,
378 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
379 .dhcp
= ADDRESS_FAMILY_NO
,
381 .dhcp_use_ntp
= true,
382 .dhcp_use_sip
= true,
383 .dhcp_use_dns
= true,
384 .dhcp_use_hostname
= true,
385 .dhcp_use_routes
= true,
386 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
387 .dhcp_send_hostname
= true,
388 .dhcp_send_release
= true,
389 /* To enable/disable RFC7844 Anonymity Profiles */
390 .dhcp_anonymize
= false,
391 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
392 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
393 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
394 .dhcp_route_table
= RT_TABLE_MAIN
,
395 .dhcp_route_table_set
= false,
396 /* NOTE: from man: UseMTU=... Defaults to false*/
397 .dhcp_use_mtu
= false,
398 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
399 .dhcp_use_timezone
= false,
400 .rapid_commit
= true,
402 .dhcp6_use_ntp
= true,
403 .dhcp6_use_dns
= true,
405 .dhcp_server_emit_dns
= true,
406 .dhcp_server_emit_ntp
= true,
407 .dhcp_server_emit_sip
= true,
408 .dhcp_server_emit_router
= true,
409 .dhcp_server_emit_timezone
= true,
411 .router_emit_dns
= true,
412 .router_emit_domains
= true,
417 .allow_port_to_be_root
= -1,
419 .multicast_flood
= -1,
420 .multicast_to_unicast
= -1,
421 .neighbor_suppression
= -1,
423 .bridge_proxy_arp
= -1,
424 .bridge_proxy_arp_wifi
= -1,
425 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
426 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
428 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
430 .dns_default_route
= -1,
431 .llmnr
= RESOLVE_SUPPORT_YES
,
432 .mdns
= RESOLVE_SUPPORT_NO
,
433 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
434 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
436 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
437 .link_local
= _ADDRESS_FAMILY_INVALID
,
439 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
440 .ipv6_accept_ra
= -1,
441 .ipv6_dad_transmits
= -1,
442 .ipv6_hop_limit
= -1,
443 .ipv6_proxy_ndp
= -1,
444 .duid
.type
= _DUID_TYPE_INVALID
,
449 .ipv6_accept_ra_use_dns
= true,
450 .ipv6_accept_ra_use_autonomous_prefix
= true,
451 .ipv6_accept_ra_use_onlink_prefix
= true,
452 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
453 .ipv6_accept_ra_route_table_set
= false,
455 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
457 .can_triple_sampling
= -1,
458 .ip_service_type
= -1,
461 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
468 "RoutingPolicyRule\0"
471 "DHCP\0" /* compat */
476 "IPv6NDPProxyAddress\0"
480 "IPv6PrefixDelegation\0"
483 "TrafficControlQueueingDiscipline\0"
488 "FairQueueingControlledDelay\0"
490 "StochasticFairnessQueueing\0"
491 "TokenBucketFilter\0"
492 "TrivialLinkEqualizer\0",
493 config_item_perf_lookup
, network_network_gperf_lookup
,
494 CONFIG_PARSE_WARN
, network
);
498 network_apply_anonymize_if_set(network
);
500 r
= network_add_ipv4ll_route(network
);
502 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
504 r
= network_add_default_route_on_device(network
);
506 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
510 if (stat(filename
, &stats
) < 0)
512 network
->timestamp
= timespec_load(&stats
.st_mtim
);
514 if (network_verify(network
) < 0)
515 /* Ignore .network files that do not match the conditions. */
518 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
522 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
530 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
531 _cleanup_strv_free_
char **files
= NULL
;
537 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
539 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
541 return log_error_errno(r
, "Failed to enumerate network files: %m");
543 STRV_FOREACH(f
, files
) {
544 r
= network_load_one(manager
, networks
, *f
);
546 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
552 int network_reload(Manager
*manager
) {
553 OrderedHashmap
*new_networks
= NULL
;
560 r
= network_load(manager
, &new_networks
);
564 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
565 r
= network_get_by_name(manager
, n
->name
, &old
);
567 continue; /* The .network file is new. */
569 if (n
->timestamp
!= old
->timestamp
)
570 continue; /* The .network file is modified. */
572 if (!streq(n
->filename
, old
->filename
))
575 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
583 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
584 manager
->networks
= new_networks
;
589 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
594 static Network
*network_free(Network
*network
) {
595 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
596 RoutePrefix
*route_prefix
;
597 RoutingPolicyRule
*rule
;
609 free(network
->filename
);
611 set_free_free(network
->match_mac
);
612 set_free_free(network
->match_permanent_mac
);
613 strv_free(network
->match_path
);
614 strv_free(network
->match_driver
);
615 strv_free(network
->match_type
);
616 strv_free(network
->match_name
);
617 strv_free(network
->match_property
);
618 strv_free(network
->match_wlan_iftype
);
619 strv_free(network
->match_ssid
);
620 set_free_free(network
->match_bssid
);
621 condition_free_list(network
->conditions
);
623 free(network
->description
);
624 free(network
->dhcp_vendor_class_identifier
);
625 strv_free(network
->dhcp_user_class
);
626 free(network
->dhcp_hostname
);
627 set_free(network
->dhcp_black_listed_ip
);
628 set_free(network
->dhcp_request_options
);
631 if (network
->dhcp_acd
)
632 sd_ipv4acd_unref(network
->dhcp_acd
);
634 strv_free(network
->ntp
);
636 strv_free(network
->sip
);
637 ordered_set_free_free(network
->search_domains
);
638 ordered_set_free_free(network
->route_domains
);
639 strv_free(network
->bind_carrier
);
641 ordered_set_free_free(network
->router_search_domains
);
642 free(network
->router_dns
);
643 set_free_free(network
->ndisc_black_listed_prefix
);
645 free(network
->bridge_name
);
646 free(network
->bond_name
);
647 free(network
->vrf_name
);
648 hashmap_free_free_key(network
->stacked_netdev_names
);
649 netdev_unref(network
->bridge
);
650 netdev_unref(network
->bond
);
651 netdev_unref(network
->vrf
);
652 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
654 while ((route
= network
->static_routes
))
657 while ((nexthop
= network
->static_nexthops
))
658 nexthop_free(nexthop
);
660 while ((address
= network
->static_addresses
))
661 address_free(address
);
663 while ((fdb_entry
= network
->static_fdb_entries
))
664 fdb_entry_free(fdb_entry
);
666 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
667 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
669 while ((neighbor
= network
->neighbors
))
670 neighbor_free(neighbor
);
672 while ((label
= network
->address_labels
))
673 address_label_free(label
);
675 while ((prefix
= network
->static_prefixes
))
678 while ((route_prefix
= network
->static_route_prefixes
))
679 route_prefix_free(route_prefix
);
681 while ((rule
= network
->rules
))
682 routing_policy_rule_free(rule
);
684 hashmap_free(network
->addresses_by_section
);
685 hashmap_free(network
->routes_by_section
);
686 hashmap_free(network
->nexthops_by_section
);
687 hashmap_free(network
->fdb_entries_by_section
);
688 hashmap_free(network
->neighbors_by_section
);
689 hashmap_free(network
->address_labels_by_section
);
690 hashmap_free(network
->prefixes_by_section
);
691 hashmap_free(network
->route_prefixes_by_section
);
692 hashmap_free(network
->rules_by_section
);
693 ordered_hashmap_free_with_destructor(network
->qdiscs_by_section
, qdisc_free
);
695 if (network
->manager
&&
696 network
->manager
->duids_requesting_uuid
)
697 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
701 free(network
->dhcp_server_timezone
);
702 free(network
->dhcp_server_dns
);
703 free(network
->dhcp_server_ntp
);
704 free(network
->dhcp_server_sip
);
706 set_free_free(network
->dnssec_negative_trust_anchors
);
708 ordered_hashmap_free(network
->dhcp_client_send_options
);
709 ordered_hashmap_free(network
->dhcp_server_send_options
);
710 ordered_hashmap_free(network
->ipv6_tokens
);
712 return mfree(network
);
715 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
717 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
724 network
= ordered_hashmap_get(manager
->networks
, name
);
733 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
734 const char *ifname
, char * const *alternative_names
,
735 const struct ether_addr
*address
, const struct ether_addr
*permanent_address
,
736 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
744 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
745 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
746 network
->match_path
, network
->match_driver
,
747 network
->match_type
, network
->match_name
, network
->match_property
,
748 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
749 iftype
, device
, address
, permanent_address
,
750 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
751 if (network
->match_name
&& device
) {
753 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
755 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
756 (void) safe_atou8(attr
, &name_assign_type
);
758 if (name_assign_type
== NET_NAME_ENUM
)
759 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
760 ifname
, network
->filename
);
762 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
764 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
775 int network_apply(Network
*network
, Link
*link
) {
779 link
->network
= network_ref(network
);
781 if (network
->n_dns
> 0 ||
782 !strv_isempty(network
->ntp
) ||
783 !ordered_set_isempty(network
->search_domains
) ||
784 !ordered_set_isempty(network
->route_domains
))
790 bool network_has_static_ipv6_configurations(Network
*network
) {
798 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
799 if (address
->family
== AF_INET6
)
802 LIST_FOREACH(routes
, route
, network
->static_routes
)
803 if (route
->family
== AF_INET6
)
806 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
807 if (fdb
->family
== AF_INET6
)
810 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
811 if (neighbor
->family
== AF_INET6
)
814 if (!LIST_IS_EMPTY(network
->address_labels
))
817 if (!LIST_IS_EMPTY(network
->static_prefixes
))
823 int config_parse_stacked_netdev(const char *unit
,
824 const char *filename
,
827 unsigned section_line
,
833 _cleanup_free_
char *name
= NULL
;
834 NetDevKind kind
= ltype
;
843 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
844 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
845 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
848 if (!ifname_valid(rvalue
)) {
849 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
850 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
854 name
= strdup(rvalue
);
858 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
862 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
864 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
865 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
867 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
868 "NetDev '%s' specified twice, ignoring.", name
);
875 int config_parse_domains(
877 const char *filename
,
880 unsigned section_line
,
895 if (isempty(rvalue
)) {
896 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
897 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
903 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
907 r
= extract_first_word(&p
, &w
, NULL
, 0);
909 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
910 "Failed to extract search or route domain, ignoring: %s", rvalue
);
916 is_route
= w
[0] == '~';
917 domain
= is_route
? w
+ 1 : w
;
919 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
920 /* If the root domain appears as is, or the special token "*" is found, we'll
921 * consider this as routing domain, unconditionally. */
923 domain
= "."; /* make sure we don't allow empty strings, thus write the root
926 r
= dns_name_normalize(domain
, 0, &normalized
);
928 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
929 "'%s' is not a valid domain name, ignoring.", domain
);
935 if (is_localhost(domain
)) {
936 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
937 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
943 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
944 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
948 r
= ordered_set_put_strdup(*set
, domain
);
956 int config_parse_ipv6token(
958 const char *filename
,
961 unsigned section_line
,
968 union in_addr_union buffer
;
969 struct in6_addr
*token
= data
;
977 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
979 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
980 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
984 if (in_addr_is_null(AF_INET6
, &buffer
)) {
985 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
986 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
990 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
991 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
992 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1001 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1002 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1003 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1004 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1007 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1008 IPV6_PRIVACY_EXTENSIONS_YES
);
1010 int config_parse_ipv6_privacy_extensions(
1012 const char *filename
,
1014 const char *section
,
1015 unsigned section_line
,
1022 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1027 assert(ipv6_privacy_extensions
);
1029 s
= ipv6_privacy_extensions_from_string(rvalue
);
1031 if (streq(rvalue
, "kernel"))
1032 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1034 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1035 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1040 *ipv6_privacy_extensions
= s
;
1045 int config_parse_hostname(
1047 const char *filename
,
1049 const char *section
,
1050 unsigned section_line
,
1057 _cleanup_free_
char *hn
= NULL
;
1058 char **hostname
= data
;
1065 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1069 if (!hostname_is_valid(hn
, false)) {
1070 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1071 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1075 r
= dns_name_is_valid(hn
);
1077 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1078 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1082 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1083 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1087 return free_and_replace(*hostname
, hn
);
1090 int config_parse_timezone(
1092 const char *filename
,
1094 const char *section
,
1095 unsigned section_line
,
1102 _cleanup_free_
char *tz
= NULL
;
1103 char **datap
= data
;
1110 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1114 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1115 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1116 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1120 return free_and_replace(*datap
, tz
);
1123 int config_parse_dns(
1125 const char *filename
,
1127 const char *section
,
1128 unsigned section_line
,
1135 Network
*n
= userdata
;
1143 _cleanup_free_
char *w
= NULL
;
1144 union in_addr_union a
;
1145 struct in_addr_data
*m
;
1148 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1152 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1153 "Invalid syntax, ignoring: %s", rvalue
);
1159 r
= in_addr_from_string_auto(w
, &family
, &a
);
1161 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1162 "Failed to parse dns server address, ignoring: %s", w
);
1166 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1170 m
[n
->n_dns
++] = (struct in_addr_data
) {
1181 int config_parse_dnssec_negative_trust_anchors(
1183 const char *filename
,
1185 const char *section
,
1186 unsigned section_line
,
1193 const char *p
= rvalue
;
1201 if (isempty(rvalue
)) {
1202 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1207 _cleanup_free_
char *w
= NULL
;
1209 r
= extract_first_word(&p
, &w
, NULL
, 0);
1211 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1212 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1218 r
= dns_name_is_valid(w
);
1220 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1221 "%s is not a valid domain name, ignoring.", w
);
1225 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1229 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1239 int config_parse_ntp(
1241 const char *filename
,
1243 const char *section
,
1244 unsigned section_line
,
1258 if (isempty(rvalue
)) {
1264 _cleanup_free_
char *w
= NULL
;
1266 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1270 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1271 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1277 r
= dns_name_is_valid_or_address(w
);
1279 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1280 "%s is not a valid domain name or IP address, ignoring.", w
);
1284 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1285 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1286 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1287 MAX_NTP_SERVERS
, w
);
1291 r
= strv_consume(l
, TAKE_PTR(w
));
1299 int config_parse_required_for_online(
1301 const char *filename
,
1303 const char *section
,
1304 unsigned section_line
,
1311 Network
*network
= data
;
1312 LinkOperationalStateRange range
;
1313 bool required
= true;
1316 if (isempty(rvalue
)) {
1317 network
->required_for_online
= true;
1318 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1322 r
= parse_operational_state_range(rvalue
, &range
);
1324 r
= parse_boolean(rvalue
);
1326 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1327 "Failed to parse %s= setting, ignoring assignment: %s",
1333 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1336 network
->required_for_online
= required
;
1337 network
->required_operstate_for_online
= range
;
1342 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1343 "Failed to parse KeepConfiguration= setting");
1345 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1346 [KEEP_CONFIGURATION_NO
] = "no",
1347 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1348 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1349 [KEEP_CONFIGURATION_STATIC
] = "static",
1350 [KEEP_CONFIGURATION_YES
] = "yes",
1353 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);