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 log_warning("%s: No valid settings found in the [Match] section. "
168 "The file will match all interfaces. "
169 "If that is intended, please 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_DEGRADED
,
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"
485 config_item_perf_lookup
, network_network_gperf_lookup
,
486 CONFIG_PARSE_WARN
, network
);
490 network_apply_anonymize_if_set(network
);
492 r
= network_add_ipv4ll_route(network
);
494 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
496 r
= network_add_default_route_on_device(network
);
498 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
502 if (stat(filename
, &stats
) < 0)
504 network
->timestamp
= timespec_load(&stats
.st_mtim
);
506 if (network_verify(network
) < 0)
507 /* Ignore .network files that do not match the conditions. */
510 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
514 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
522 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
523 _cleanup_strv_free_
char **files
= NULL
;
529 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
531 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
533 return log_error_errno(r
, "Failed to enumerate network files: %m");
535 STRV_FOREACH(f
, files
) {
536 r
= network_load_one(manager
, networks
, *f
);
538 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
544 int network_reload(Manager
*manager
) {
545 OrderedHashmap
*new_networks
= NULL
;
552 r
= network_load(manager
, &new_networks
);
556 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
557 r
= network_get_by_name(manager
, n
->name
, &old
);
559 continue; /* The .network file is new. */
561 if (n
->timestamp
!= old
->timestamp
)
562 continue; /* The .network file is modified. */
564 if (!streq(n
->filename
, old
->filename
))
567 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
575 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
576 manager
->networks
= new_networks
;
581 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
586 static Network
*network_free(Network
*network
) {
587 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
588 RoutePrefix
*route_prefix
;
589 RoutingPolicyRule
*rule
;
601 free(network
->filename
);
603 set_free_free(network
->match_mac
);
604 set_free_free(network
->match_permanent_mac
);
605 strv_free(network
->match_path
);
606 strv_free(network
->match_driver
);
607 strv_free(network
->match_type
);
608 strv_free(network
->match_name
);
609 strv_free(network
->match_property
);
610 strv_free(network
->match_wlan_iftype
);
611 strv_free(network
->match_ssid
);
612 set_free_free(network
->match_bssid
);
613 condition_free_list(network
->conditions
);
615 free(network
->description
);
616 free(network
->dhcp_vendor_class_identifier
);
617 strv_free(network
->dhcp_user_class
);
618 free(network
->dhcp_hostname
);
619 set_free(network
->dhcp_black_listed_ip
);
620 set_free(network
->dhcp_request_options
);
623 if (network
->dhcp_acd
)
624 sd_ipv4acd_unref(network
->dhcp_acd
);
626 strv_free(network
->ntp
);
628 strv_free(network
->sip
);
629 ordered_set_free_free(network
->search_domains
);
630 ordered_set_free_free(network
->route_domains
);
631 strv_free(network
->bind_carrier
);
633 ordered_set_free_free(network
->router_search_domains
);
634 free(network
->router_dns
);
635 set_free_free(network
->ndisc_black_listed_prefix
);
637 free(network
->bridge_name
);
638 free(network
->bond_name
);
639 free(network
->vrf_name
);
640 hashmap_free_free_key(network
->stacked_netdev_names
);
641 netdev_unref(network
->bridge
);
642 netdev_unref(network
->bond
);
643 netdev_unref(network
->vrf
);
644 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
646 while ((route
= network
->static_routes
))
649 while ((nexthop
= network
->static_nexthops
))
650 nexthop_free(nexthop
);
652 while ((address
= network
->static_addresses
))
653 address_free(address
);
655 while ((fdb_entry
= network
->static_fdb_entries
))
656 fdb_entry_free(fdb_entry
);
658 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
659 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
661 while ((neighbor
= network
->neighbors
))
662 neighbor_free(neighbor
);
664 while ((label
= network
->address_labels
))
665 address_label_free(label
);
667 while ((prefix
= network
->static_prefixes
))
670 while ((route_prefix
= network
->static_route_prefixes
))
671 route_prefix_free(route_prefix
);
673 while ((rule
= network
->rules
))
674 routing_policy_rule_free(rule
);
676 hashmap_free(network
->addresses_by_section
);
677 hashmap_free(network
->routes_by_section
);
678 hashmap_free(network
->nexthops_by_section
);
679 hashmap_free(network
->fdb_entries_by_section
);
680 hashmap_free(network
->neighbors_by_section
);
681 hashmap_free(network
->address_labels_by_section
);
682 hashmap_free(network
->prefixes_by_section
);
683 hashmap_free(network
->route_prefixes_by_section
);
684 hashmap_free(network
->rules_by_section
);
685 ordered_hashmap_free_with_destructor(network
->qdiscs_by_section
, qdisc_free
);
687 if (network
->manager
&&
688 network
->manager
->duids_requesting_uuid
)
689 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
693 free(network
->dhcp_server_timezone
);
694 free(network
->dhcp_server_dns
);
695 free(network
->dhcp_server_ntp
);
696 free(network
->dhcp_server_sip
);
698 set_free_free(network
->dnssec_negative_trust_anchors
);
700 ordered_hashmap_free(network
->dhcp_client_send_options
);
701 ordered_hashmap_free(network
->dhcp_server_send_options
);
703 return mfree(network
);
706 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
708 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
715 network
= ordered_hashmap_get(manager
->networks
, name
);
724 int network_get(Manager
*manager
, sd_device
*device
,
725 const char *ifname
, char * const *alternative_names
,
726 const struct ether_addr
*address
, const struct ether_addr
*permanent_address
,
727 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
735 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
736 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
737 network
->match_path
, network
->match_driver
,
738 network
->match_type
, network
->match_name
, network
->match_property
,
739 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
740 device
, address
, permanent_address
,
741 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
742 if (network
->match_name
&& device
) {
744 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
746 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
747 (void) safe_atou8(attr
, &name_assign_type
);
749 if (name_assign_type
== NET_NAME_ENUM
)
750 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
751 ifname
, network
->filename
);
753 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
755 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
766 int network_apply(Network
*network
, Link
*link
) {
770 link
->network
= network_ref(network
);
772 if (network
->n_dns
> 0 ||
773 !strv_isempty(network
->ntp
) ||
774 !ordered_set_isempty(network
->search_domains
) ||
775 !ordered_set_isempty(network
->route_domains
))
781 bool network_has_static_ipv6_configurations(Network
*network
) {
789 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
790 if (address
->family
== AF_INET6
)
793 LIST_FOREACH(routes
, route
, network
->static_routes
)
794 if (route
->family
== AF_INET6
)
797 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
798 if (fdb
->family
== AF_INET6
)
801 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
802 if (neighbor
->family
== AF_INET6
)
805 if (!LIST_IS_EMPTY(network
->address_labels
))
808 if (!LIST_IS_EMPTY(network
->static_prefixes
))
814 int config_parse_stacked_netdev(const char *unit
,
815 const char *filename
,
818 unsigned section_line
,
824 _cleanup_free_
char *name
= NULL
;
825 NetDevKind kind
= ltype
;
834 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
835 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
836 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
839 if (!ifname_valid(rvalue
)) {
840 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
841 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
845 name
= strdup(rvalue
);
849 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
853 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
855 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
856 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
858 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
859 "NetDev '%s' specified twice, ignoring.", name
);
866 int config_parse_domains(
868 const char *filename
,
871 unsigned section_line
,
886 if (isempty(rvalue
)) {
887 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
888 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
894 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
898 r
= extract_first_word(&p
, &w
, NULL
, 0);
900 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
901 "Failed to extract search or route domain, ignoring: %s", rvalue
);
907 is_route
= w
[0] == '~';
908 domain
= is_route
? w
+ 1 : w
;
910 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
911 /* If the root domain appears as is, or the special token "*" is found, we'll
912 * consider this as routing domain, unconditionally. */
914 domain
= "."; /* make sure we don't allow empty strings, thus write the root
917 r
= dns_name_normalize(domain
, 0, &normalized
);
919 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
920 "'%s' is not a valid domain name, ignoring.", domain
);
926 if (is_localhost(domain
)) {
927 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
928 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
934 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
935 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
939 r
= ordered_set_put_strdup(*set
, domain
);
947 int config_parse_ipv6token(
949 const char *filename
,
952 unsigned section_line
,
959 union in_addr_union buffer
;
960 struct in6_addr
*token
= data
;
968 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
970 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
971 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
975 if (in_addr_is_null(AF_INET6
, &buffer
)) {
976 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
977 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
981 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
982 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
983 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
992 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
993 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
994 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
995 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
998 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
999 IPV6_PRIVACY_EXTENSIONS_YES
);
1001 int config_parse_ipv6_privacy_extensions(
1003 const char *filename
,
1005 const char *section
,
1006 unsigned section_line
,
1013 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1018 assert(ipv6_privacy_extensions
);
1020 s
= ipv6_privacy_extensions_from_string(rvalue
);
1022 if (streq(rvalue
, "kernel"))
1023 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1025 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1026 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1031 *ipv6_privacy_extensions
= s
;
1036 int config_parse_hostname(
1038 const char *filename
,
1040 const char *section
,
1041 unsigned section_line
,
1048 _cleanup_free_
char *hn
= NULL
;
1049 char **hostname
= data
;
1056 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1060 if (!hostname_is_valid(hn
, false)) {
1061 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1062 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1066 r
= dns_name_is_valid(hn
);
1068 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1069 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1073 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1074 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1078 return free_and_replace(*hostname
, hn
);
1081 int config_parse_timezone(
1083 const char *filename
,
1085 const char *section
,
1086 unsigned section_line
,
1093 _cleanup_free_
char *tz
= NULL
;
1094 char **datap
= data
;
1101 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1105 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1106 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1107 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1111 return free_and_replace(*datap
, tz
);
1114 int config_parse_dns(
1116 const char *filename
,
1118 const char *section
,
1119 unsigned section_line
,
1126 Network
*n
= userdata
;
1134 _cleanup_free_
char *w
= NULL
;
1135 union in_addr_union a
;
1136 struct in_addr_data
*m
;
1139 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1143 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1144 "Invalid syntax, ignoring: %s", rvalue
);
1150 r
= in_addr_from_string_auto(w
, &family
, &a
);
1152 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1153 "Failed to parse dns server address, ignoring: %s", w
);
1157 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1161 m
[n
->n_dns
++] = (struct in_addr_data
) {
1172 int config_parse_dnssec_negative_trust_anchors(
1174 const char *filename
,
1176 const char *section
,
1177 unsigned section_line
,
1184 const char *p
= rvalue
;
1192 if (isempty(rvalue
)) {
1193 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1198 _cleanup_free_
char *w
= NULL
;
1200 r
= extract_first_word(&p
, &w
, NULL
, 0);
1202 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1203 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1209 r
= dns_name_is_valid(w
);
1211 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1212 "%s is not a valid domain name, ignoring.", w
);
1216 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1220 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1230 int config_parse_ntp(
1232 const char *filename
,
1234 const char *section
,
1235 unsigned section_line
,
1249 if (isempty(rvalue
)) {
1255 _cleanup_free_
char *w
= NULL
;
1257 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1261 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1262 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1268 r
= dns_name_is_valid_or_address(w
);
1270 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1271 "%s is not a valid domain name or IP address, ignoring.", w
);
1275 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1276 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1277 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1278 MAX_NTP_SERVERS
, w
);
1282 r
= strv_consume(l
, TAKE_PTR(w
));
1290 int config_parse_required_for_online(
1292 const char *filename
,
1294 const char *section
,
1295 unsigned section_line
,
1302 Network
*network
= data
;
1303 LinkOperationalState s
;
1304 bool required
= true;
1307 if (isempty(rvalue
)) {
1308 network
->required_for_online
= true;
1309 network
->required_operstate_for_online
= LINK_OPERSTATE_DEGRADED
;
1313 s
= link_operstate_from_string(rvalue
);
1315 r
= parse_boolean(rvalue
);
1317 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1318 "Failed to parse %s= setting, ignoring assignment: %s",
1324 s
= LINK_OPERSTATE_DEGRADED
;
1327 network
->required_for_online
= required
;
1328 network
->required_operstate_for_online
= s
;
1333 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1334 "Failed to parse KeepConfiguration= setting");
1336 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1337 [KEEP_CONFIGURATION_NO
] = "no",
1338 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1339 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1340 [KEEP_CONFIGURATION_STATIC
] = "static",
1341 [KEEP_CONFIGURATION_YES
] = "yes",
1344 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);