1 /* SPDX-License-Identifier: LGPL-2.1+ */
4 #include <netinet/in.h>
5 #include <linux/netdevice.h>
8 #include "alloc-util.h"
9 #include "conf-files.h"
10 #include "conf-parser.h"
11 #include "dns-domain.h"
13 #include "hostname-util.h"
14 #include "in-addr-util.h"
15 #include "networkd-dhcp-server.h"
16 #include "network-internal.h"
17 #include "networkd-manager.h"
18 #include "networkd-network.h"
19 #include "parse-util.h"
20 #include "path-lookup.h"
22 #include "socket-util.h"
23 #include "stat-util.h"
24 #include "string-table.h"
25 #include "string-util.h"
30 /* Let's assume that anything above this number is a user misconfiguration. */
31 #define MAX_NTP_SERVERS 128
33 /* Set defaults following RFC7844 */
34 void network_apply_anonymize_if_set(Network
*network
) {
35 if (!network
->dhcp_anonymize
)
38 SHOULD NOT send the Host Name option */
39 network
->dhcp_send_hostname
= false;
40 /* RFC7844 section 3.:
41 MAY contain the Client Identifier option
43 clients MUST use client identifiers based solely
44 on the link-layer address */
45 /* NOTE: Using MAC, as it does not reveal extra information,
46 * and some servers might not answer if this option is not sent */
47 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
49 SHOULD NOT use the Vendor Class Identifier option */
50 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
51 /* RFC7844 section 3.6.:
52 The client intending to protect its privacy SHOULD only request a
53 minimal number of options in the PRL and SHOULD also randomly shuffle
54 the ordering of option codes in the PRL. If this random ordering
55 cannot be implemented, the client MAY order the option codes in the
56 PRL by option code number (lowest to highest).
58 /* NOTE: dhcp_use_mtu is false by default,
59 * though it was not initiallized to any value in network_load_one.
60 * Maybe there should be another var called *send*?
61 * (to use the MTU sent by the server but to do not send
62 * the option in the PRL). */
63 network
->dhcp_use_mtu
= false;
64 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
65 * but this is needed to use them. */
66 network
->dhcp_use_routes
= true;
67 /* RFC7844 section 3.6.
68 * same comments as previous option */
69 network
->dhcp_use_timezone
= false;
72 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
73 const char *kind_string
;
77 /* For test-networkd-conf, the check must be earlier than the assertions. */
82 assert(network
->manager
);
83 assert(network
->filename
);
86 if (kind
== _NETDEV_KIND_TUNNEL
)
87 kind_string
= "tunnel";
89 kind_string
= netdev_kind_to_string(kind
);
91 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
92 "%s: Invalid NetDev kind of %s, ignoring assignment.",
93 network
->filename
, name
);
96 r
= netdev_get(network
->manager
, name
, &netdev
);
98 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
99 network
->filename
, name
);
101 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
108 NETDEV_KIND_IP6GRETAP
,
112 NETDEV_KIND_ERSPAN
)))
113 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
114 "%s: NetDev %s is not a %s, ignoring assignment",
115 network
->filename
, name
, kind_string
);
117 *ret_netdev
= netdev_ref(netdev
);
121 static int network_resolve_stacked_netdevs(Network
*network
) {
128 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
129 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
131 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
135 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
139 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
141 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
142 network
->filename
, (const char *) name
);
150 int network_verify(Network
*network
) {
151 RoutePrefix
*route_prefix
, *route_prefix_next
;
152 RoutingPolicyRule
*rule
, *rule_next
;
153 Neighbor
*neighbor
, *neighbor_next
;
154 AddressLabel
*label
, *label_next
;
155 NextHop
*nexthop
, *nextnop_next
;
156 Address
*address
, *address_next
;
157 Prefix
*prefix
, *prefix_next
;
158 Route
*route
, *route_next
;
159 FdbEntry
*fdb
, *fdb_next
;
164 assert(network
->filename
);
166 if (set_isempty(network
->match_mac
) && set_isempty(network
->match_permanent_mac
) &&
167 strv_isempty(network
->match_path
) && strv_isempty(network
->match_driver
) &&
168 strv_isempty(network
->match_type
) && strv_isempty(network
->match_name
) &&
169 strv_isempty(network
->match_property
) && strv_isempty(network
->match_ssid
) && !network
->conditions
)
170 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
171 "%s: No valid settings found in the [Match] section, ignoring file. "
172 "To match all interfaces, add Name=* in the [Match] section.",
175 /* skip out early if configuration does not match the environment */
176 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
177 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
178 "%s: Conditions in the file do not match the system environment, skipping.",
181 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
182 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
183 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
184 (void) network_resolve_stacked_netdevs(network
);
186 /* Free unnecessary entries. */
187 network
->bond_name
= mfree(network
->bond_name
);
188 network
->bridge_name
= mfree(network
->bridge_name
);
189 network
->vrf_name
= mfree(network
->vrf_name
);
190 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
193 /* Bonding slave does not support addressing. */
194 if (network
->ipv6_accept_ra
> 0) {
195 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
197 network
->ipv6_accept_ra
= 0;
199 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
200 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
202 network
->link_local
= ADDRESS_FAMILY_NO
;
204 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
205 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
207 network
->dhcp
= ADDRESS_FAMILY_NO
;
209 if (network
->dhcp_server
) {
210 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
212 network
->dhcp_server
= false;
214 if (network
->n_static_addresses
> 0) {
215 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
217 while ((address
= network
->static_addresses
))
218 address_free(address
);
220 if (network
->n_static_routes
> 0) {
221 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
223 while ((route
= network
->static_routes
))
228 if (network
->link_local
< 0)
229 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
231 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
232 if (network
->ipv6_accept_ra
> 0) {
233 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
234 "Disabling IPv6AcceptRA=.", network
->filename
);
235 network
->ipv6_accept_ra
= false;
238 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
239 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
240 "Disabling DHCPv6 client.", network
->filename
);
241 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
244 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
245 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
246 "Disabling IPv6PrefixDelegation=.", network
->filename
);
247 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
251 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
252 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
253 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
254 "Disabling the fallback assignment.", network
->filename
);
255 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
258 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
259 network
->ipv6_accept_ra
= false;
261 /* IPMasquerade=yes implies IPForward=yes */
262 if (network
->ip_masquerade
)
263 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
265 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
266 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
267 "Disabling UseMTU=.", network
->filename
);
268 network
->dhcp_use_mtu
= false;
271 if (network
->dhcp_use_gateway
< 0)
272 network
->dhcp_use_gateway
= network
->dhcp_use_routes
;
274 if (network
->dhcp_critical
>= 0) {
275 if (network
->keep_configuration
>= 0)
276 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
277 "Ignoring CriticalConnection=.", network
->filename
);
278 else if (network
->dhcp_critical
)
279 /* CriticalConnection=yes also preserve foreign static configurations. */
280 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
282 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
285 if (network
->keep_configuration
< 0)
286 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
288 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
289 if (address_section_verify(address
) < 0)
290 address_free(address
);
292 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
293 if (route_section_verify(route
, network
) < 0)
296 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
297 if (nexthop_section_verify(nexthop
) < 0)
298 nexthop_free(nexthop
);
300 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
301 if (section_is_invalid(fdb
->section
))
304 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
305 if (neighbor_section_verify(neighbor
) < 0)
306 neighbor_free(neighbor
);
308 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
309 if (section_is_invalid(label
->section
))
310 address_label_free(label
);
312 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
313 if (section_is_invalid(prefix
->section
))
316 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
317 if (section_is_invalid(route_prefix
->section
))
318 route_prefix_free(route_prefix
);
320 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
321 if (routing_policy_rule_section_verify(rule
) < 0)
322 routing_policy_rule_free(rule
);
324 bool has_root
= false, has_clsact
= false;
325 ORDERED_HASHMAP_FOREACH(tc
, network
->tc_by_section
, i
)
326 if (traffic_control_section_verify(tc
, &has_root
, &has_clsact
) < 0)
327 traffic_control_free(tc
);
332 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
333 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
334 _cleanup_(network_unrefp
) Network
*network
= NULL
;
335 _cleanup_fclose_
FILE *file
= NULL
;
336 const char *dropin_dirname
;
343 file
= fopen(filename
, "re");
351 if (null_or_empty_fd(fileno(file
))) {
352 log_debug("Skipping empty file: %s", filename
);
356 fname
= strdup(filename
);
360 name
= strdup(basename(filename
));
364 d
= strrchr(name
, '.');
370 dropin_dirname
= strjoina(name
, ".network.d");
372 network
= new(Network
, 1);
376 *network
= (Network
) {
377 .filename
= TAKE_PTR(fname
),
378 .name
= TAKE_PTR(name
),
383 .required_for_online
= true,
384 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
385 .dhcp
= ADDRESS_FAMILY_NO
,
387 .dhcp_use_ntp
= true,
388 .dhcp_use_sip
= true,
389 .dhcp_use_dns
= true,
390 .dhcp_use_hostname
= true,
391 .dhcp_use_routes
= true,
392 .dhcp_use_gateway
= -1,
393 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
394 .dhcp_send_hostname
= true,
395 .dhcp_send_release
= true,
396 /* To enable/disable RFC7844 Anonymity Profiles */
397 .dhcp_anonymize
= false,
398 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
399 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
400 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
401 .dhcp_route_table
= RT_TABLE_MAIN
,
402 .dhcp_route_table_set
= false,
403 /* NOTE: from man: UseMTU=... Defaults to false*/
404 .dhcp_use_mtu
= false,
405 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
406 .dhcp_use_timezone
= false,
407 .rapid_commit
= true,
409 .dhcp6_use_ntp
= true,
410 .dhcp6_use_dns
= true,
412 .dhcp_server_emit_dns
= true,
413 .dhcp_server_emit_ntp
= true,
414 .dhcp_server_emit_sip
= true,
415 .dhcp_server_emit_router
= true,
416 .dhcp_server_emit_timezone
= true,
418 .router_emit_dns
= true,
419 .router_emit_domains
= true,
424 .allow_port_to_be_root
= -1,
426 .multicast_flood
= -1,
427 .multicast_to_unicast
= -1,
428 .neighbor_suppression
= -1,
430 .bridge_proxy_arp
= -1,
431 .bridge_proxy_arp_wifi
= -1,
432 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
433 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
435 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
437 .dns_default_route
= -1,
438 .llmnr
= RESOLVE_SUPPORT_YES
,
439 .mdns
= RESOLVE_SUPPORT_NO
,
440 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
441 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
443 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
444 .link_local
= _ADDRESS_FAMILY_INVALID
,
446 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
447 .ipv6_accept_ra
= -1,
448 .ipv6_dad_transmits
= -1,
449 .ipv6_hop_limit
= -1,
450 .ipv6_proxy_ndp
= -1,
451 .duid
.type
= _DUID_TYPE_INVALID
,
456 .ipv6_accept_ra_use_dns
= true,
457 .ipv6_accept_ra_use_autonomous_prefix
= true,
458 .ipv6_accept_ra_use_onlink_prefix
= true,
459 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
460 .ipv6_accept_ra_route_table_set
= false,
461 .ipv6_accept_ra_start_dhcp6_client
= true,
463 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
464 .ipv6_address_gen_mode
= _LINK_IPV6_ADDRESS_GEN_MODE_INVALID
,
465 .can_triple_sampling
= -1,
466 .can_termination
= -1,
467 .ip_service_type
= -1,
470 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
477 "RoutingPolicyRule\0"
480 "DHCP\0" /* compat */
485 "IPv6NDPProxyAddress\0"
489 "IPv6PrefixDelegation\0"
493 "TrafficControlQueueingDiscipline\0"
499 "DeficitRoundRobinScheduler\0"
500 "DeficitRoundRobinSchedulerClass\0"
505 "FairQueueingControlledDelay\0"
506 "GenericRandomEarlyDetection\0"
507 "HeavyHitterFilter\0"
508 "HierarchyTokenBucket\0"
509 "HierarchyTokenBucketClass\0"
512 "StochasticFairBlue\0"
513 "StochasticFairnessQueueing\0"
514 "TokenBucketFilter\0"
515 "TrivialLinkEqualizer\0",
516 config_item_perf_lookup
, network_network_gperf_lookup
,
517 CONFIG_PARSE_WARN
, network
);
521 network_apply_anonymize_if_set(network
);
523 r
= network_add_ipv4ll_route(network
);
525 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
527 r
= network_add_default_route_on_device(network
);
529 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
533 if (stat(filename
, &stats
) < 0)
535 network
->timestamp
= timespec_load(&stats
.st_mtim
);
537 if (network_verify(network
) < 0)
538 /* Ignore .network files that do not match the conditions. */
541 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
545 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
553 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
554 _cleanup_strv_free_
char **files
= NULL
;
560 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
562 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
564 return log_error_errno(r
, "Failed to enumerate network files: %m");
566 STRV_FOREACH(f
, files
) {
567 r
= network_load_one(manager
, networks
, *f
);
569 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
575 int network_reload(Manager
*manager
) {
576 OrderedHashmap
*new_networks
= NULL
;
583 r
= network_load(manager
, &new_networks
);
587 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
588 r
= network_get_by_name(manager
, n
->name
, &old
);
590 continue; /* The .network file is new. */
592 if (n
->timestamp
!= old
->timestamp
)
593 continue; /* The .network file is modified. */
595 if (!streq(n
->filename
, old
->filename
))
598 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
606 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
607 manager
->networks
= new_networks
;
612 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
617 static Network
*network_free(Network
*network
) {
618 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
619 RoutePrefix
*route_prefix
;
620 RoutingPolicyRule
*rule
;
632 free(network
->filename
);
634 set_free_free(network
->match_mac
);
635 set_free_free(network
->match_permanent_mac
);
636 strv_free(network
->match_path
);
637 strv_free(network
->match_driver
);
638 strv_free(network
->match_type
);
639 strv_free(network
->match_name
);
640 strv_free(network
->match_property
);
641 strv_free(network
->match_wlan_iftype
);
642 strv_free(network
->match_ssid
);
643 set_free_free(network
->match_bssid
);
644 condition_free_list(network
->conditions
);
646 free(network
->description
);
647 free(network
->dhcp_vendor_class_identifier
);
648 free(network
->dhcp_mudurl
);
649 strv_free(network
->dhcp_user_class
);
650 free(network
->dhcp_hostname
);
651 set_free(network
->dhcp_black_listed_ip
);
652 set_free(network
->dhcp_request_options
);
653 set_free(network
->dhcp6_request_options
);
655 free(network
->dhcp6_mudurl
);
656 strv_free(network
->dhcp6_user_class
);
657 strv_free(network
->dhcp6_vendor_class
);
659 if (network
->dhcp_acd
)
660 sd_ipv4acd_unref(network
->dhcp_acd
);
662 strv_free(network
->ntp
);
664 strv_free(network
->sip
);
665 strv_free(network
->smtp
);
666 ordered_set_free_free(network
->search_domains
);
667 ordered_set_free_free(network
->route_domains
);
668 strv_free(network
->bind_carrier
);
670 ordered_set_free_free(network
->router_search_domains
);
671 free(network
->router_dns
);
672 set_free_free(network
->ndisc_black_listed_prefix
);
674 free(network
->bridge_name
);
675 free(network
->bond_name
);
676 free(network
->vrf_name
);
677 hashmap_free_free_key(network
->stacked_netdev_names
);
678 netdev_unref(network
->bridge
);
679 netdev_unref(network
->bond
);
680 netdev_unref(network
->vrf
);
681 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
683 while ((route
= network
->static_routes
))
686 while ((nexthop
= network
->static_nexthops
))
687 nexthop_free(nexthop
);
689 while ((address
= network
->static_addresses
))
690 address_free(address
);
692 while ((fdb_entry
= network
->static_fdb_entries
))
693 fdb_entry_free(fdb_entry
);
695 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
696 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
698 while ((neighbor
= network
->neighbors
))
699 neighbor_free(neighbor
);
701 while ((label
= network
->address_labels
))
702 address_label_free(label
);
704 while ((prefix
= network
->static_prefixes
))
707 while ((route_prefix
= network
->static_route_prefixes
))
708 route_prefix_free(route_prefix
);
710 while ((rule
= network
->rules
))
711 routing_policy_rule_free(rule
);
713 hashmap_free(network
->addresses_by_section
);
714 hashmap_free(network
->routes_by_section
);
715 hashmap_free(network
->nexthops_by_section
);
716 hashmap_free(network
->fdb_entries_by_section
);
717 hashmap_free(network
->neighbors_by_section
);
718 hashmap_free(network
->address_labels_by_section
);
719 hashmap_free(network
->prefixes_by_section
);
720 hashmap_free(network
->route_prefixes_by_section
);
721 hashmap_free(network
->rules_by_section
);
722 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
724 if (network
->manager
&&
725 network
->manager
->duids_requesting_uuid
)
726 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
730 free(network
->dhcp_server_timezone
);
731 free(network
->dhcp_server_dns
);
732 free(network
->dhcp_server_ntp
);
733 free(network
->dhcp_server_sip
);
735 set_free_free(network
->dnssec_negative_trust_anchors
);
737 free(network
->lldp_mud
);
739 ordered_hashmap_free(network
->dhcp_client_send_options
);
740 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
741 ordered_hashmap_free(network
->dhcp_server_send_options
);
742 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
743 ordered_hashmap_free(network
->ipv6_tokens
);
745 return mfree(network
);
748 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
750 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
757 network
= ordered_hashmap_get(manager
->networks
, name
);
766 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
767 const char *ifname
, char * const *alternative_names
,
768 const struct ether_addr
*address
, const struct ether_addr
*permanent_address
,
769 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
777 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
778 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
779 network
->match_path
, network
->match_driver
,
780 network
->match_type
, network
->match_name
, network
->match_property
,
781 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
782 iftype
, device
, address
, permanent_address
,
783 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
784 if (network
->match_name
&& device
) {
786 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
788 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
789 (void) safe_atou8(attr
, &name_assign_type
);
791 if (name_assign_type
== NET_NAME_ENUM
)
792 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
793 ifname
, network
->filename
);
795 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
797 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
808 int network_apply(Network
*network
, Link
*link
) {
812 link
->network
= network_ref(network
);
814 if (network
->n_dns
> 0 ||
815 !strv_isempty(network
->ntp
) ||
816 !ordered_set_isempty(network
->search_domains
) ||
817 !ordered_set_isempty(network
->route_domains
))
823 bool network_has_static_ipv6_configurations(Network
*network
) {
831 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
832 if (address
->family
== AF_INET6
)
835 LIST_FOREACH(routes
, route
, network
->static_routes
)
836 if (route
->family
== AF_INET6
)
839 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
840 if (fdb
->family
== AF_INET6
)
843 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
844 if (neighbor
->family
== AF_INET6
)
847 if (!LIST_IS_EMPTY(network
->address_labels
))
850 if (!LIST_IS_EMPTY(network
->static_prefixes
))
856 int config_parse_stacked_netdev(const char *unit
,
857 const char *filename
,
860 unsigned section_line
,
866 _cleanup_free_
char *name
= NULL
;
867 NetDevKind kind
= ltype
;
876 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
877 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
878 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
881 if (!ifname_valid(rvalue
)) {
882 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
883 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
887 name
= strdup(rvalue
);
891 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
895 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
897 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
898 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
900 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
901 "NetDev '%s' specified twice, ignoring.", name
);
908 int config_parse_domains(
910 const char *filename
,
913 unsigned section_line
,
928 if (isempty(rvalue
)) {
929 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
930 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
936 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
940 r
= extract_first_word(&p
, &w
, NULL
, 0);
942 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
943 "Failed to extract search or route domain, ignoring: %s", rvalue
);
949 is_route
= w
[0] == '~';
950 domain
= is_route
? w
+ 1 : w
;
952 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
953 /* If the root domain appears as is, or the special token "*" is found, we'll
954 * consider this as routing domain, unconditionally. */
956 domain
= "."; /* make sure we don't allow empty strings, thus write the root
959 r
= dns_name_normalize(domain
, 0, &normalized
);
961 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
962 "'%s' is not a valid domain name, ignoring.", domain
);
968 if (is_localhost(domain
)) {
969 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
970 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
976 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
977 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
981 r
= ordered_set_put_strdup(*set
, domain
);
989 int config_parse_ipv6token(
991 const char *filename
,
994 unsigned section_line
,
1001 union in_addr_union buffer
;
1002 struct in6_addr
*token
= data
;
1010 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
1012 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1013 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1017 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1018 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1019 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1023 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1024 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1025 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1029 *token
= buffer
.in6
;
1034 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1035 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1036 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1037 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1040 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1041 IPV6_PRIVACY_EXTENSIONS_YES
);
1043 int config_parse_ipv6_privacy_extensions(
1045 const char *filename
,
1047 const char *section
,
1048 unsigned section_line
,
1055 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1060 assert(ipv6_privacy_extensions
);
1062 s
= ipv6_privacy_extensions_from_string(rvalue
);
1064 if (streq(rvalue
, "kernel"))
1065 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1067 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1068 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1073 *ipv6_privacy_extensions
= s
;
1078 int config_parse_hostname(
1080 const char *filename
,
1082 const char *section
,
1083 unsigned section_line
,
1090 _cleanup_free_
char *hn
= NULL
;
1091 char **hostname
= data
;
1098 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1102 if (!hostname_is_valid(hn
, false)) {
1103 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1104 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1108 r
= dns_name_is_valid(hn
);
1110 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1111 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1115 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1116 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1120 return free_and_replace(*hostname
, hn
);
1123 int config_parse_timezone(
1125 const char *filename
,
1127 const char *section
,
1128 unsigned section_line
,
1135 _cleanup_free_
char *tz
= NULL
;
1136 char **datap
= data
;
1143 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1147 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1148 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1149 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1153 return free_and_replace(*datap
, tz
);
1156 int config_parse_dns(
1158 const char *filename
,
1160 const char *section
,
1161 unsigned section_line
,
1168 Network
*n
= userdata
;
1176 _cleanup_free_
char *w
= NULL
;
1177 union in_addr_union a
;
1178 struct in_addr_data
*m
;
1181 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1185 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1186 "Invalid syntax, ignoring: %s", rvalue
);
1192 r
= in_addr_from_string_auto(w
, &family
, &a
);
1194 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1195 "Failed to parse dns server address, ignoring: %s", w
);
1199 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1203 m
[n
->n_dns
++] = (struct in_addr_data
) {
1214 int config_parse_dnssec_negative_trust_anchors(
1216 const char *filename
,
1218 const char *section
,
1219 unsigned section_line
,
1226 const char *p
= rvalue
;
1234 if (isempty(rvalue
)) {
1235 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1240 _cleanup_free_
char *w
= NULL
;
1242 r
= extract_first_word(&p
, &w
, NULL
, 0);
1244 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1245 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1251 r
= dns_name_is_valid(w
);
1253 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1254 "%s is not a valid domain name, ignoring.", w
);
1258 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1262 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1272 int config_parse_ntp(
1274 const char *filename
,
1276 const char *section
,
1277 unsigned section_line
,
1291 if (isempty(rvalue
)) {
1297 _cleanup_free_
char *w
= NULL
;
1299 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1303 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1304 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1310 r
= dns_name_is_valid_or_address(w
);
1312 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1313 "%s is not a valid domain name or IP address, ignoring.", w
);
1317 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1318 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1319 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1320 MAX_NTP_SERVERS
, w
);
1324 r
= strv_consume(l
, TAKE_PTR(w
));
1332 int config_parse_required_for_online(
1334 const char *filename
,
1336 const char *section
,
1337 unsigned section_line
,
1344 Network
*network
= data
;
1345 LinkOperationalStateRange range
;
1346 bool required
= true;
1349 if (isempty(rvalue
)) {
1350 network
->required_for_online
= true;
1351 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1355 r
= parse_operational_state_range(rvalue
, &range
);
1357 r
= parse_boolean(rvalue
);
1359 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1360 "Failed to parse %s= setting, ignoring assignment: %s",
1366 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1369 network
->required_for_online
= required
;
1370 network
->required_operstate_for_online
= range
;
1375 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1376 "Failed to parse KeepConfiguration= setting");
1378 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1379 [KEEP_CONFIGURATION_NO
] = "no",
1380 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1381 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1382 [KEEP_CONFIGURATION_STATIC
] = "static",
1383 [KEEP_CONFIGURATION_YES
] = "yes",
1386 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);