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"
28 /* Let's assume that anything above this number is a user misconfiguration. */
29 #define MAX_NTP_SERVERS 128
31 /* Set defaults following RFC7844 */
32 void network_apply_anonymize_if_set(Network
*network
) {
33 if (!network
->dhcp_anonymize
)
36 SHOULD NOT send the Host Name option */
37 network
->dhcp_send_hostname
= false;
38 /* RFC7844 section 3.:
39 MAY contain the Client Identifier option
41 clients MUST use client identifiers based solely
42 on the link-layer address */
43 /* NOTE: Using MAC, as it does not reveal extra information,
44 * and some servers might not answer if this option is not sent */
45 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
47 SHOULD NOT use the Vendor Class Identifier option */
48 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
49 /* RFC7844 section 3.6.:
50 The client intending to protect its privacy SHOULD only request a
51 minimal number of options in the PRL and SHOULD also randomly shuffle
52 the ordering of option codes in the PRL. If this random ordering
53 cannot be implemented, the client MAY order the option codes in the
54 PRL by option code number (lowest to highest).
56 /* NOTE: dhcp_use_mtu is false by default,
57 * though it was not initiallized to any value in network_load_one.
58 * Maybe there should be another var called *send*?
59 * (to use the MTU sent by the server but to do not send
60 * the option in the PRL). */
61 network
->dhcp_use_mtu
= false;
62 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
63 * but this is needed to use them. */
64 network
->dhcp_use_routes
= true;
65 /* RFC7844 section 3.6.
66 * same comments as previous option */
67 network
->dhcp_use_timezone
= false;
70 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
71 const char *kind_string
;
75 /* For test-networkd-conf, the check must be earlier than the assertions. */
80 assert(network
->manager
);
81 assert(network
->filename
);
84 if (kind
== _NETDEV_KIND_TUNNEL
)
85 kind_string
= "tunnel";
87 kind_string
= netdev_kind_to_string(kind
);
89 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
90 "%s: Invalid NetDev kind of %s, ignoring assignment.",
91 network
->filename
, name
);
94 r
= netdev_get(network
->manager
, name
, &netdev
);
96 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
97 network
->filename
, name
);
99 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
106 NETDEV_KIND_IP6GRETAP
,
110 NETDEV_KIND_ERSPAN
)))
111 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
112 "%s: NetDev %s is not a %s, ignoring assignment",
113 network
->filename
, name
, kind_string
);
115 *ret_netdev
= netdev_ref(netdev
);
119 static int network_resolve_stacked_netdevs(Network
*network
) {
126 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
127 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
129 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
133 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
137 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
139 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
140 network
->filename
, (const char *) name
);
148 int network_verify(Network
*network
) {
149 RoutePrefix
*route_prefix
, *route_prefix_next
;
150 RoutingPolicyRule
*rule
, *rule_next
;
151 Neighbor
*neighbor
, *neighbor_next
;
152 AddressLabel
*label
, *label_next
;
153 NextHop
*nexthop
, *nextnop_next
;
154 Address
*address
, *address_next
;
155 Prefix
*prefix
, *prefix_next
;
156 Route
*route
, *route_next
;
157 FdbEntry
*fdb
, *fdb_next
;
162 assert(network
->filename
);
164 if (set_isempty(network
->match_mac
) && set_isempty(network
->match_permanent_mac
) &&
165 strv_isempty(network
->match_path
) && strv_isempty(network
->match_driver
) &&
166 strv_isempty(network
->match_type
) && strv_isempty(network
->match_name
) &&
167 strv_isempty(network
->match_property
) && strv_isempty(network
->match_ssid
) && !network
->conditions
)
168 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
169 "%s: No valid settings found in the [Match] section, ignoring file. "
170 "To match all interfaces, add Name=* in the [Match] section.",
173 /* skip out early if configuration does not match the environment */
174 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
175 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
176 "%s: Conditions in the file do not match the system environment, skipping.",
179 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
180 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
181 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
182 (void) network_resolve_stacked_netdevs(network
);
184 /* Free unnecessary entries. */
185 network
->bond_name
= mfree(network
->bond_name
);
186 network
->bridge_name
= mfree(network
->bridge_name
);
187 network
->vrf_name
= mfree(network
->vrf_name
);
188 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
191 /* Bonding slave does not support addressing. */
192 if (network
->ipv6_accept_ra
> 0) {
193 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
195 network
->ipv6_accept_ra
= 0;
197 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
198 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
200 network
->link_local
= ADDRESS_FAMILY_NO
;
202 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
203 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
205 network
->dhcp
= ADDRESS_FAMILY_NO
;
207 if (network
->dhcp_server
) {
208 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
210 network
->dhcp_server
= false;
212 if (network
->n_static_addresses
> 0) {
213 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
215 while ((address
= network
->static_addresses
))
216 address_free(address
);
218 if (network
->n_static_routes
> 0) {
219 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
221 while ((route
= network
->static_routes
))
226 if (network
->link_local
< 0)
227 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
229 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
230 if (network
->ipv6_accept_ra
> 0) {
231 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
232 "Disabling IPv6AcceptRA=.", network
->filename
);
233 network
->ipv6_accept_ra
= false;
236 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
237 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
238 "Disabling DHCPv6 client.", network
->filename
);
239 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
242 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
243 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
244 "Disabling IPv6PrefixDelegation=.", network
->filename
);
245 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
249 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
250 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
251 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
252 "Disabling the fallback assignment.", network
->filename
);
253 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
256 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
257 network
->ipv6_accept_ra
= false;
259 /* IPMasquerade=yes implies IPForward=yes */
260 if (network
->ip_masquerade
)
261 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
263 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
264 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
265 "Disabling UseMTU=.", network
->filename
);
266 network
->dhcp_use_mtu
= false;
269 if (network
->dhcp_critical
>= 0) {
270 if (network
->keep_configuration
>= 0)
271 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
272 "Ignoring CriticalConnection=.", network
->filename
);
273 else if (network
->dhcp_critical
)
274 /* CriticalConnection=yes also preserve foreign static configurations. */
275 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
277 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
280 if (network
->keep_configuration
< 0)
281 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
283 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
284 if (address_section_verify(address
) < 0)
285 address_free(address
);
287 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
288 if (route_section_verify(route
, network
) < 0)
291 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
292 if (nexthop_section_verify(nexthop
) < 0)
293 nexthop_free(nexthop
);
295 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
296 if (section_is_invalid(fdb
->section
))
299 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
300 if (neighbor_section_verify(neighbor
) < 0)
301 neighbor_free(neighbor
);
303 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
304 if (section_is_invalid(label
->section
))
305 address_label_free(label
);
307 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
308 if (section_is_invalid(prefix
->section
))
311 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
312 if (section_is_invalid(route_prefix
->section
))
313 route_prefix_free(route_prefix
);
315 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
316 if (routing_policy_rule_section_verify(rule
) < 0)
317 routing_policy_rule_free(rule
);
319 bool has_root
= false, has_clsact
= false;
320 ORDERED_HASHMAP_FOREACH(tc
, network
->tc_by_section
, i
)
321 if (traffic_control_section_verify(tc
, &has_root
, &has_clsact
) < 0)
322 traffic_control_free(tc
);
327 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
328 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
329 _cleanup_(network_unrefp
) Network
*network
= NULL
;
330 _cleanup_fclose_
FILE *file
= NULL
;
331 const char *dropin_dirname
;
338 file
= fopen(filename
, "re");
346 if (null_or_empty_fd(fileno(file
))) {
347 log_debug("Skipping empty file: %s", filename
);
351 fname
= strdup(filename
);
355 name
= strdup(basename(filename
));
359 d
= strrchr(name
, '.');
365 dropin_dirname
= strjoina(name
, ".network.d");
367 network
= new(Network
, 1);
371 *network
= (Network
) {
372 .filename
= TAKE_PTR(fname
),
373 .name
= TAKE_PTR(name
),
378 .required_for_online
= true,
379 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
380 .dhcp
= ADDRESS_FAMILY_NO
,
382 .dhcp_use_ntp
= true,
383 .dhcp_use_sip
= true,
384 .dhcp_use_dns
= true,
385 .dhcp_use_hostname
= true,
386 .dhcp_use_routes
= true,
387 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
388 .dhcp_send_hostname
= true,
389 .dhcp_send_release
= true,
390 /* To enable/disable RFC7844 Anonymity Profiles */
391 .dhcp_anonymize
= false,
392 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
393 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
394 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
395 .dhcp_route_table
= RT_TABLE_MAIN
,
396 .dhcp_route_table_set
= false,
397 /* NOTE: from man: UseMTU=... Defaults to false*/
398 .dhcp_use_mtu
= false,
399 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
400 .dhcp_use_timezone
= false,
401 .rapid_commit
= true,
403 .dhcp6_use_ntp
= true,
404 .dhcp6_use_dns
= true,
406 .dhcp_server_emit_dns
= true,
407 .dhcp_server_emit_ntp
= true,
408 .dhcp_server_emit_sip
= true,
409 .dhcp_server_emit_router
= true,
410 .dhcp_server_emit_timezone
= true,
412 .router_emit_dns
= true,
413 .router_emit_domains
= true,
418 .allow_port_to_be_root
= -1,
420 .multicast_flood
= -1,
421 .multicast_to_unicast
= -1,
422 .neighbor_suppression
= -1,
424 .bridge_proxy_arp
= -1,
425 .bridge_proxy_arp_wifi
= -1,
426 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
427 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
429 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
431 .dns_default_route
= -1,
432 .llmnr
= RESOLVE_SUPPORT_YES
,
433 .mdns
= RESOLVE_SUPPORT_NO
,
434 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
435 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
437 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
438 .link_local
= _ADDRESS_FAMILY_INVALID
,
440 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
441 .ipv6_accept_ra
= -1,
442 .ipv6_dad_transmits
= -1,
443 .ipv6_hop_limit
= -1,
444 .ipv6_proxy_ndp
= -1,
445 .duid
.type
= _DUID_TYPE_INVALID
,
450 .ipv6_accept_ra_use_dns
= true,
451 .ipv6_accept_ra_use_autonomous_prefix
= true,
452 .ipv6_accept_ra_use_onlink_prefix
= true,
453 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
454 .ipv6_accept_ra_route_table_set
= false,
455 .ipv6_accept_ra_start_dhcp6_client
= true,
457 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
459 .can_triple_sampling
= -1,
460 .can_termination
= -1,
461 .ip_service_type
= -1,
464 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
471 "RoutingPolicyRule\0"
474 "DHCP\0" /* compat */
479 "IPv6NDPProxyAddress\0"
483 "IPv6PrefixDelegation\0"
486 "TrafficControlQueueingDiscipline\0"
492 "DeficitRoundRobinScheduler\0"
493 "DeficitRoundRobinSchedulerClass\0"
496 "FairQueueingControlledDelay\0"
497 "GenericRandomEarlyDetection\0"
498 "HierarchyTokenBucket\0"
499 "HierarchyTokenBucketClass\0"
502 "StochasticFairBlue\0"
503 "StochasticFairnessQueueing\0"
504 "TokenBucketFilter\0"
505 "TrivialLinkEqualizer\0",
506 config_item_perf_lookup
, network_network_gperf_lookup
,
507 CONFIG_PARSE_WARN
, network
);
511 network_apply_anonymize_if_set(network
);
513 r
= network_add_ipv4ll_route(network
);
515 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
517 r
= network_add_default_route_on_device(network
);
519 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
523 if (stat(filename
, &stats
) < 0)
525 network
->timestamp
= timespec_load(&stats
.st_mtim
);
527 if (network_verify(network
) < 0)
528 /* Ignore .network files that do not match the conditions. */
531 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
535 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
543 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
544 _cleanup_strv_free_
char **files
= NULL
;
550 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
552 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
554 return log_error_errno(r
, "Failed to enumerate network files: %m");
556 STRV_FOREACH(f
, files
) {
557 r
= network_load_one(manager
, networks
, *f
);
559 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
565 int network_reload(Manager
*manager
) {
566 OrderedHashmap
*new_networks
= NULL
;
573 r
= network_load(manager
, &new_networks
);
577 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
578 r
= network_get_by_name(manager
, n
->name
, &old
);
580 continue; /* The .network file is new. */
582 if (n
->timestamp
!= old
->timestamp
)
583 continue; /* The .network file is modified. */
585 if (!streq(n
->filename
, old
->filename
))
588 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
596 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
597 manager
->networks
= new_networks
;
602 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
607 static Network
*network_free(Network
*network
) {
608 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
609 RoutePrefix
*route_prefix
;
610 RoutingPolicyRule
*rule
;
622 free(network
->filename
);
624 set_free_free(network
->match_mac
);
625 set_free_free(network
->match_permanent_mac
);
626 strv_free(network
->match_path
);
627 strv_free(network
->match_driver
);
628 strv_free(network
->match_type
);
629 strv_free(network
->match_name
);
630 strv_free(network
->match_property
);
631 strv_free(network
->match_wlan_iftype
);
632 strv_free(network
->match_ssid
);
633 set_free_free(network
->match_bssid
);
634 condition_free_list(network
->conditions
);
636 free(network
->description
);
637 free(network
->dhcp_vendor_class_identifier
);
638 strv_free(network
->dhcp_user_class
);
639 free(network
->dhcp_hostname
);
640 set_free(network
->dhcp_black_listed_ip
);
641 set_free(network
->dhcp_request_options
);
644 if (network
->dhcp_acd
)
645 sd_ipv4acd_unref(network
->dhcp_acd
);
647 strv_free(network
->ntp
);
649 strv_free(network
->sip
);
650 ordered_set_free_free(network
->search_domains
);
651 ordered_set_free_free(network
->route_domains
);
652 strv_free(network
->bind_carrier
);
654 ordered_set_free_free(network
->router_search_domains
);
655 free(network
->router_dns
);
656 set_free_free(network
->ndisc_black_listed_prefix
);
658 free(network
->bridge_name
);
659 free(network
->bond_name
);
660 free(network
->vrf_name
);
661 hashmap_free_free_key(network
->stacked_netdev_names
);
662 netdev_unref(network
->bridge
);
663 netdev_unref(network
->bond
);
664 netdev_unref(network
->vrf
);
665 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
667 while ((route
= network
->static_routes
))
670 while ((nexthop
= network
->static_nexthops
))
671 nexthop_free(nexthop
);
673 while ((address
= network
->static_addresses
))
674 address_free(address
);
676 while ((fdb_entry
= network
->static_fdb_entries
))
677 fdb_entry_free(fdb_entry
);
679 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
680 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
682 while ((neighbor
= network
->neighbors
))
683 neighbor_free(neighbor
);
685 while ((label
= network
->address_labels
))
686 address_label_free(label
);
688 while ((prefix
= network
->static_prefixes
))
691 while ((route_prefix
= network
->static_route_prefixes
))
692 route_prefix_free(route_prefix
);
694 while ((rule
= network
->rules
))
695 routing_policy_rule_free(rule
);
697 hashmap_free(network
->addresses_by_section
);
698 hashmap_free(network
->routes_by_section
);
699 hashmap_free(network
->nexthops_by_section
);
700 hashmap_free(network
->fdb_entries_by_section
);
701 hashmap_free(network
->neighbors_by_section
);
702 hashmap_free(network
->address_labels_by_section
);
703 hashmap_free(network
->prefixes_by_section
);
704 hashmap_free(network
->route_prefixes_by_section
);
705 hashmap_free(network
->rules_by_section
);
706 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
708 if (network
->manager
&&
709 network
->manager
->duids_requesting_uuid
)
710 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
714 free(network
->dhcp_server_timezone
);
715 free(network
->dhcp_server_dns
);
716 free(network
->dhcp_server_ntp
);
717 free(network
->dhcp_server_sip
);
719 set_free_free(network
->dnssec_negative_trust_anchors
);
721 ordered_hashmap_free(network
->dhcp_client_send_options
);
722 ordered_hashmap_free(network
->dhcp_server_send_options
);
723 ordered_hashmap_free(network
->ipv6_tokens
);
725 return mfree(network
);
728 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
730 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
737 network
= ordered_hashmap_get(manager
->networks
, name
);
746 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
747 const char *ifname
, char * const *alternative_names
,
748 const struct ether_addr
*address
, const struct ether_addr
*permanent_address
,
749 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
757 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
758 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
759 network
->match_path
, network
->match_driver
,
760 network
->match_type
, network
->match_name
, network
->match_property
,
761 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
762 iftype
, device
, address
, permanent_address
,
763 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
764 if (network
->match_name
&& device
) {
766 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
768 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
769 (void) safe_atou8(attr
, &name_assign_type
);
771 if (name_assign_type
== NET_NAME_ENUM
)
772 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
773 ifname
, network
->filename
);
775 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
777 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
788 int network_apply(Network
*network
, Link
*link
) {
792 link
->network
= network_ref(network
);
794 if (network
->n_dns
> 0 ||
795 !strv_isempty(network
->ntp
) ||
796 !ordered_set_isempty(network
->search_domains
) ||
797 !ordered_set_isempty(network
->route_domains
))
803 bool network_has_static_ipv6_configurations(Network
*network
) {
811 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
812 if (address
->family
== AF_INET6
)
815 LIST_FOREACH(routes
, route
, network
->static_routes
)
816 if (route
->family
== AF_INET6
)
819 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
820 if (fdb
->family
== AF_INET6
)
823 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
824 if (neighbor
->family
== AF_INET6
)
827 if (!LIST_IS_EMPTY(network
->address_labels
))
830 if (!LIST_IS_EMPTY(network
->static_prefixes
))
836 int config_parse_stacked_netdev(const char *unit
,
837 const char *filename
,
840 unsigned section_line
,
846 _cleanup_free_
char *name
= NULL
;
847 NetDevKind kind
= ltype
;
856 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
857 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
858 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
861 if (!ifname_valid(rvalue
)) {
862 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
863 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
867 name
= strdup(rvalue
);
871 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
875 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
877 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
878 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
880 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
881 "NetDev '%s' specified twice, ignoring.", name
);
888 int config_parse_domains(
890 const char *filename
,
893 unsigned section_line
,
908 if (isempty(rvalue
)) {
909 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
910 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
916 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
920 r
= extract_first_word(&p
, &w
, NULL
, 0);
922 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
923 "Failed to extract search or route domain, ignoring: %s", rvalue
);
929 is_route
= w
[0] == '~';
930 domain
= is_route
? w
+ 1 : w
;
932 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
933 /* If the root domain appears as is, or the special token "*" is found, we'll
934 * consider this as routing domain, unconditionally. */
936 domain
= "."; /* make sure we don't allow empty strings, thus write the root
939 r
= dns_name_normalize(domain
, 0, &normalized
);
941 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
942 "'%s' is not a valid domain name, ignoring.", domain
);
948 if (is_localhost(domain
)) {
949 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
950 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
956 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
957 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
961 r
= ordered_set_put_strdup(*set
, domain
);
969 int config_parse_ipv6token(
971 const char *filename
,
974 unsigned section_line
,
981 union in_addr_union buffer
;
982 struct in6_addr
*token
= data
;
990 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
992 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
993 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
997 if (in_addr_is_null(AF_INET6
, &buffer
)) {
998 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
999 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1003 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1004 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1005 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1009 *token
= buffer
.in6
;
1014 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1015 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1016 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1017 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1020 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1021 IPV6_PRIVACY_EXTENSIONS_YES
);
1023 int config_parse_ipv6_privacy_extensions(
1025 const char *filename
,
1027 const char *section
,
1028 unsigned section_line
,
1035 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1040 assert(ipv6_privacy_extensions
);
1042 s
= ipv6_privacy_extensions_from_string(rvalue
);
1044 if (streq(rvalue
, "kernel"))
1045 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1047 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1048 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1053 *ipv6_privacy_extensions
= s
;
1058 int config_parse_hostname(
1060 const char *filename
,
1062 const char *section
,
1063 unsigned section_line
,
1070 _cleanup_free_
char *hn
= NULL
;
1071 char **hostname
= data
;
1078 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1082 if (!hostname_is_valid(hn
, false)) {
1083 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1084 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1088 r
= dns_name_is_valid(hn
);
1090 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1091 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1095 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1096 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1100 return free_and_replace(*hostname
, hn
);
1103 int config_parse_timezone(
1105 const char *filename
,
1107 const char *section
,
1108 unsigned section_line
,
1115 _cleanup_free_
char *tz
= NULL
;
1116 char **datap
= data
;
1123 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1127 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1128 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1129 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1133 return free_and_replace(*datap
, tz
);
1136 int config_parse_dns(
1138 const char *filename
,
1140 const char *section
,
1141 unsigned section_line
,
1148 Network
*n
= userdata
;
1156 _cleanup_free_
char *w
= NULL
;
1157 union in_addr_union a
;
1158 struct in_addr_data
*m
;
1161 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1165 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1166 "Invalid syntax, ignoring: %s", rvalue
);
1172 r
= in_addr_from_string_auto(w
, &family
, &a
);
1174 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1175 "Failed to parse dns server address, ignoring: %s", w
);
1179 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1183 m
[n
->n_dns
++] = (struct in_addr_data
) {
1194 int config_parse_dnssec_negative_trust_anchors(
1196 const char *filename
,
1198 const char *section
,
1199 unsigned section_line
,
1206 const char *p
= rvalue
;
1214 if (isempty(rvalue
)) {
1215 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1220 _cleanup_free_
char *w
= NULL
;
1222 r
= extract_first_word(&p
, &w
, NULL
, 0);
1224 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1225 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1231 r
= dns_name_is_valid(w
);
1233 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1234 "%s is not a valid domain name, ignoring.", w
);
1238 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1242 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1252 int config_parse_ntp(
1254 const char *filename
,
1256 const char *section
,
1257 unsigned section_line
,
1271 if (isempty(rvalue
)) {
1277 _cleanup_free_
char *w
= NULL
;
1279 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1283 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1284 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1290 r
= dns_name_is_valid_or_address(w
);
1292 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1293 "%s is not a valid domain name or IP address, ignoring.", w
);
1297 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1298 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1299 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1300 MAX_NTP_SERVERS
, w
);
1304 r
= strv_consume(l
, TAKE_PTR(w
));
1312 int config_parse_required_for_online(
1314 const char *filename
,
1316 const char *section
,
1317 unsigned section_line
,
1324 Network
*network
= data
;
1325 LinkOperationalStateRange range
;
1326 bool required
= true;
1329 if (isempty(rvalue
)) {
1330 network
->required_for_online
= true;
1331 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1335 r
= parse_operational_state_range(rvalue
, &range
);
1337 r
= parse_boolean(rvalue
);
1339 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1340 "Failed to parse %s= setting, ignoring assignment: %s",
1346 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1349 network
->required_for_online
= required
;
1350 network
->required_operstate_for_online
= range
;
1355 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1356 "Failed to parse KeepConfiguration= setting");
1358 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1359 [KEEP_CONFIGURATION_NO
] = "no",
1360 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1361 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1362 [KEEP_CONFIGURATION_STATIC
] = "static",
1363 [KEEP_CONFIGURATION_YES
] = "yes",
1366 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);