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
->ignore_carrier_loss
< 0)
275 network
->ignore_carrier_loss
= network
->configure_without_carrier
;
277 if (network
->dhcp_critical
>= 0) {
278 if (network
->keep_configuration
>= 0)
279 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
280 "Ignoring CriticalConnection=.", network
->filename
);
281 else if (network
->dhcp_critical
)
282 /* CriticalConnection=yes also preserve foreign static configurations. */
283 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
285 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
288 if (network
->keep_configuration
< 0)
289 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
291 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
292 if (address_section_verify(address
) < 0)
293 address_free(address
);
295 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
296 if (route_section_verify(route
, network
) < 0)
299 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
300 if (nexthop_section_verify(nexthop
) < 0)
301 nexthop_free(nexthop
);
303 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
304 if (section_is_invalid(fdb
->section
))
307 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
308 if (neighbor_section_verify(neighbor
) < 0)
309 neighbor_free(neighbor
);
311 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
312 if (section_is_invalid(label
->section
))
313 address_label_free(label
);
315 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
316 if (section_is_invalid(prefix
->section
))
319 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
320 if (section_is_invalid(route_prefix
->section
))
321 route_prefix_free(route_prefix
);
323 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
324 if (routing_policy_rule_section_verify(rule
) < 0)
325 routing_policy_rule_free(rule
);
327 bool has_root
= false, has_clsact
= false;
328 ORDERED_HASHMAP_FOREACH(tc
, network
->tc_by_section
, i
)
329 if (traffic_control_section_verify(tc
, &has_root
, &has_clsact
) < 0)
330 traffic_control_free(tc
);
335 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
336 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
337 _cleanup_(network_unrefp
) Network
*network
= NULL
;
338 _cleanup_fclose_
FILE *file
= NULL
;
339 const char *dropin_dirname
;
346 file
= fopen(filename
, "re");
354 if (null_or_empty_fd(fileno(file
))) {
355 log_debug("Skipping empty file: %s", filename
);
359 fname
= strdup(filename
);
363 name
= strdup(basename(filename
));
367 d
= strrchr(name
, '.');
373 dropin_dirname
= strjoina(name
, ".network.d");
375 network
= new(Network
, 1);
379 *network
= (Network
) {
380 .filename
= TAKE_PTR(fname
),
381 .name
= TAKE_PTR(name
),
386 .required_for_online
= true,
387 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
388 .dhcp
= ADDRESS_FAMILY_NO
,
390 .dhcp_use_ntp
= true,
391 .dhcp_use_sip
= true,
392 .dhcp_use_dns
= true,
393 .dhcp_use_hostname
= true,
394 .dhcp_use_routes
= true,
395 .dhcp_use_gateway
= -1,
396 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
397 .dhcp_send_hostname
= true,
398 .dhcp_send_release
= true,
399 /* To enable/disable RFC7844 Anonymity Profiles */
400 .dhcp_anonymize
= false,
401 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
402 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
403 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
404 .dhcp_route_table
= RT_TABLE_MAIN
,
405 .dhcp_route_table_set
= false,
406 /* NOTE: from man: UseMTU=... Defaults to false*/
407 .dhcp_use_mtu
= false,
408 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
409 .dhcp_use_timezone
= false,
410 .rapid_commit
= true,
412 .dhcp6_route_metric
= DHCP_ROUTE_METRIC
,
413 .dhcp6_use_ntp
= true,
414 .dhcp6_use_dns
= true,
416 .dhcp6_pd_assign_prefix
= true,
418 .dhcp_server_emit_dns
= true,
419 .dhcp_server_emit_ntp
= true,
420 .dhcp_server_emit_sip
= true,
421 .dhcp_server_emit_router
= true,
422 .dhcp_server_emit_timezone
= true,
424 .router_prefix_subnet_id
= -1,
425 .router_emit_dns
= true,
426 .router_emit_domains
= true,
431 .allow_port_to_be_root
= -1,
433 .multicast_flood
= -1,
434 .multicast_to_unicast
= -1,
435 .neighbor_suppression
= -1,
437 .bridge_proxy_arp
= -1,
438 .bridge_proxy_arp_wifi
= -1,
439 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
440 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
442 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
444 .dns_default_route
= -1,
445 .llmnr
= RESOLVE_SUPPORT_YES
,
446 .mdns
= RESOLVE_SUPPORT_NO
,
447 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
448 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
450 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
451 .link_local
= _ADDRESS_FAMILY_INVALID
,
453 .ipv4_accept_local
= -1,
455 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
456 .ipv6_accept_ra
= -1,
457 .ipv6_dad_transmits
= -1,
458 .ipv6_hop_limit
= -1,
459 .ipv6_proxy_ndp
= -1,
460 .duid
.type
= _DUID_TYPE_INVALID
,
465 .ipv6_accept_ra_use_dns
= true,
466 .ipv6_accept_ra_use_autonomous_prefix
= true,
467 .ipv6_accept_ra_use_onlink_prefix
= true,
468 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
469 .ipv6_accept_ra_route_table_set
= false,
470 .ipv6_accept_ra_start_dhcp6_client
= true,
472 .configure_without_carrier
= false,
473 .ignore_carrier_loss
= -1,
474 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
475 .ipv6_address_gen_mode
= _LINK_IPV6_ADDRESS_GEN_MODE_INVALID
,
476 .can_triple_sampling
= -1,
477 .can_termination
= -1,
478 .ip_service_type
= -1,
481 r
= config_parse_many(
482 filename
, NETWORK_DIRS
, dropin_dirname
,
489 "RoutingPolicyRule\0"
492 "DHCP\0" /* compat */
497 "IPv6NDPProxyAddress\0"
501 "IPv6PrefixDelegation\0"
505 "TrafficControlQueueingDiscipline\0"
511 "DeficitRoundRobinScheduler\0"
512 "DeficitRoundRobinSchedulerClass\0"
514 "FairQueueingControlledDelay\0"
515 "GenericRandomEarlyDetection\0"
516 "HeavyHitterFilter\0"
517 "HierarchyTokenBucket\0"
518 "HierarchyTokenBucketClass\0"
524 "QuickFairQueueing\0"
525 "QuickFairQueueingClass\0"
526 "StochasticFairBlue\0"
527 "StochasticFairnessQueueing\0"
528 "TokenBucketFilter\0"
529 "TrivialLinkEqualizer\0",
530 config_item_perf_lookup
, network_network_gperf_lookup
,
533 &network
->timestamp
);
537 network_apply_anonymize_if_set(network
);
539 r
= network_add_ipv4ll_route(network
);
541 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
543 r
= network_add_default_route_on_device(network
);
545 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
548 if (network_verify(network
) < 0)
549 /* Ignore .network files that do not match the conditions. */
552 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
556 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
564 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
565 _cleanup_strv_free_
char **files
= NULL
;
571 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
573 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
575 return log_error_errno(r
, "Failed to enumerate network files: %m");
577 STRV_FOREACH(f
, files
) {
578 r
= network_load_one(manager
, networks
, *f
);
580 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
586 int network_reload(Manager
*manager
) {
587 OrderedHashmap
*new_networks
= NULL
;
594 r
= network_load(manager
, &new_networks
);
598 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
599 r
= network_get_by_name(manager
, n
->name
, &old
);
601 continue; /* The .network file is new. */
603 if (n
->timestamp
!= old
->timestamp
)
604 continue; /* The .network file is modified. */
606 if (!streq(n
->filename
, old
->filename
))
609 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
617 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
618 manager
->networks
= new_networks
;
623 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
628 static Network
*network_free(Network
*network
) {
629 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
630 RoutePrefix
*route_prefix
;
631 RoutingPolicyRule
*rule
;
643 free(network
->filename
);
645 set_free_free(network
->match_mac
);
646 set_free_free(network
->match_permanent_mac
);
647 strv_free(network
->match_path
);
648 strv_free(network
->match_driver
);
649 strv_free(network
->match_type
);
650 strv_free(network
->match_name
);
651 strv_free(network
->match_property
);
652 strv_free(network
->match_wlan_iftype
);
653 strv_free(network
->match_ssid
);
654 set_free_free(network
->match_bssid
);
655 condition_free_list(network
->conditions
);
657 free(network
->description
);
658 free(network
->dhcp_vendor_class_identifier
);
659 free(network
->dhcp_mudurl
);
660 strv_free(network
->dhcp_user_class
);
661 free(network
->dhcp_hostname
);
662 set_free(network
->dhcp_black_listed_ip
);
663 set_free(network
->dhcp_request_options
);
664 set_free(network
->dhcp6_request_options
);
666 free(network
->dhcp6_mudurl
);
667 strv_free(network
->dhcp6_user_class
);
668 strv_free(network
->dhcp6_vendor_class
);
670 if (network
->dhcp_acd
)
671 sd_ipv4acd_unref(network
->dhcp_acd
);
673 strv_free(network
->ntp
);
675 strv_free(network
->sip
);
676 strv_free(network
->smtp
);
677 ordered_set_free_free(network
->search_domains
);
678 ordered_set_free_free(network
->route_domains
);
679 strv_free(network
->bind_carrier
);
681 ordered_set_free_free(network
->router_search_domains
);
682 free(network
->router_dns
);
683 set_free_free(network
->ndisc_black_listed_prefix
);
685 free(network
->bridge_name
);
686 free(network
->bond_name
);
687 free(network
->vrf_name
);
688 hashmap_free_free_key(network
->stacked_netdev_names
);
689 netdev_unref(network
->bridge
);
690 netdev_unref(network
->bond
);
691 netdev_unref(network
->vrf
);
692 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
694 while ((route
= network
->static_routes
))
697 while ((nexthop
= network
->static_nexthops
))
698 nexthop_free(nexthop
);
700 while ((address
= network
->static_addresses
))
701 address_free(address
);
703 while ((fdb_entry
= network
->static_fdb_entries
))
704 fdb_entry_free(fdb_entry
);
706 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
707 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
709 while ((neighbor
= network
->neighbors
))
710 neighbor_free(neighbor
);
712 while ((label
= network
->address_labels
))
713 address_label_free(label
);
715 while ((prefix
= network
->static_prefixes
))
718 while ((route_prefix
= network
->static_route_prefixes
))
719 route_prefix_free(route_prefix
);
721 while ((rule
= network
->rules
))
722 routing_policy_rule_free(rule
);
724 hashmap_free(network
->addresses_by_section
);
725 hashmap_free(network
->routes_by_section
);
726 hashmap_free(network
->nexthops_by_section
);
727 hashmap_free(network
->fdb_entries_by_section
);
728 hashmap_free(network
->neighbors_by_section
);
729 hashmap_free(network
->address_labels_by_section
);
730 hashmap_free(network
->prefixes_by_section
);
731 hashmap_free(network
->route_prefixes_by_section
);
732 hashmap_free(network
->rules_by_section
);
733 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
735 if (network
->manager
&&
736 network
->manager
->duids_requesting_uuid
)
737 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
741 free(network
->dhcp_server_timezone
);
742 free(network
->dhcp_server_dns
);
743 free(network
->dhcp_server_ntp
);
744 free(network
->dhcp_server_sip
);
745 free(network
->dhcp_server_pop3
);
746 free(network
->dhcp_server_smtp
);
747 free(network
->dhcp_server_lpr
);
749 set_free_free(network
->dnssec_negative_trust_anchors
);
751 free(network
->lldp_mud
);
753 ordered_hashmap_free(network
->dhcp_client_send_options
);
754 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
755 ordered_hashmap_free(network
->dhcp_server_send_options
);
756 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
757 ordered_hashmap_free(network
->ipv6_tokens
);
758 ordered_hashmap_free(network
->dhcp6_client_send_options
);
759 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
761 return mfree(network
);
764 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
766 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
773 network
= ordered_hashmap_get(manager
->networks
, name
);
782 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
783 const char *ifname
, char * const *alternative_names
, const char *driver
,
784 const struct ether_addr
*mac
, const struct ether_addr
*permanent_mac
,
785 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
793 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
794 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
795 network
->match_path
, network
->match_driver
,
796 network
->match_type
, network
->match_name
, network
->match_property
,
797 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
798 device
, mac
, permanent_mac
, driver
, iftype
,
799 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
800 if (network
->match_name
&& device
) {
802 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
804 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
805 (void) safe_atou8(attr
, &name_assign_type
);
807 if (name_assign_type
== NET_NAME_ENUM
)
808 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
809 ifname
, network
->filename
);
811 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
813 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
824 int network_apply(Network
*network
, Link
*link
) {
828 link
->network
= network_ref(network
);
830 if (network
->n_dns
> 0 ||
831 !strv_isempty(network
->ntp
) ||
832 !ordered_set_isempty(network
->search_domains
) ||
833 !ordered_set_isempty(network
->route_domains
))
839 bool network_has_static_ipv6_configurations(Network
*network
) {
847 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
848 if (address
->family
== AF_INET6
)
851 LIST_FOREACH(routes
, route
, network
->static_routes
)
852 if (route
->family
== AF_INET6
)
855 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
856 if (fdb
->family
== AF_INET6
)
859 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
860 if (neighbor
->family
== AF_INET6
)
863 if (!LIST_IS_EMPTY(network
->address_labels
))
866 if (!LIST_IS_EMPTY(network
->static_prefixes
))
872 int config_parse_stacked_netdev(const char *unit
,
873 const char *filename
,
876 unsigned section_line
,
882 _cleanup_free_
char *name
= NULL
;
883 NetDevKind kind
= ltype
;
892 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
893 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
894 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
897 if (!ifname_valid(rvalue
)) {
898 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
899 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
903 name
= strdup(rvalue
);
907 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
911 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
913 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
914 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
916 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
917 "NetDev '%s' specified twice, ignoring.", name
);
924 int config_parse_domains(
926 const char *filename
,
929 unsigned section_line
,
944 if (isempty(rvalue
)) {
945 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
946 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
952 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
956 r
= extract_first_word(&p
, &w
, NULL
, 0);
958 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
959 "Failed to extract search or route domain, ignoring: %s", rvalue
);
965 is_route
= w
[0] == '~';
966 domain
= is_route
? w
+ 1 : w
;
968 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
969 /* If the root domain appears as is, or the special token "*" is found, we'll
970 * consider this as routing domain, unconditionally. */
972 domain
= "."; /* make sure we don't allow empty strings, thus write the root
975 r
= dns_name_normalize(domain
, 0, &normalized
);
977 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
978 "'%s' is not a valid domain name, ignoring.", domain
);
984 if (is_localhost(domain
)) {
985 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
986 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
992 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
993 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
997 r
= ordered_set_put_strdup(*set
, domain
);
1005 int config_parse_ipv6token(
1007 const char *filename
,
1009 const char *section
,
1010 unsigned section_line
,
1017 union in_addr_union buffer
;
1018 struct in6_addr
*token
= data
;
1026 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
1028 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1029 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1033 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1034 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1035 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1039 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1040 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1041 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1045 *token
= buffer
.in6
;
1050 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1051 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1052 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1053 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1056 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1057 IPV6_PRIVACY_EXTENSIONS_YES
);
1059 int config_parse_ipv6_privacy_extensions(
1061 const char *filename
,
1063 const char *section
,
1064 unsigned section_line
,
1071 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1076 assert(ipv6_privacy_extensions
);
1078 s
= ipv6_privacy_extensions_from_string(rvalue
);
1080 if (streq(rvalue
, "kernel"))
1081 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1083 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1084 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1089 *ipv6_privacy_extensions
= s
;
1094 int config_parse_hostname(
1096 const char *filename
,
1098 const char *section
,
1099 unsigned section_line
,
1106 _cleanup_free_
char *hn
= NULL
;
1107 char **hostname
= data
;
1114 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1118 if (!hostname_is_valid(hn
, false)) {
1119 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1120 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1124 r
= dns_name_is_valid(hn
);
1126 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1127 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1131 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1132 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1136 return free_and_replace(*hostname
, hn
);
1139 int config_parse_timezone(
1141 const char *filename
,
1143 const char *section
,
1144 unsigned section_line
,
1151 _cleanup_free_
char *tz
= NULL
;
1152 char **datap
= data
;
1159 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1163 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1164 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1165 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1169 return free_and_replace(*datap
, tz
);
1172 int config_parse_dns(
1174 const char *filename
,
1176 const char *section
,
1177 unsigned section_line
,
1184 Network
*n
= userdata
;
1192 _cleanup_free_
char *w
= NULL
;
1193 union in_addr_union a
;
1194 struct in_addr_data
*m
;
1197 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1201 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1202 "Invalid syntax, ignoring: %s", rvalue
);
1208 r
= in_addr_from_string_auto(w
, &family
, &a
);
1210 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1211 "Failed to parse dns server address, ignoring: %s", w
);
1215 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1219 m
[n
->n_dns
++] = (struct in_addr_data
) {
1230 int config_parse_dnssec_negative_trust_anchors(
1232 const char *filename
,
1234 const char *section
,
1235 unsigned section_line
,
1242 const char *p
= rvalue
;
1250 if (isempty(rvalue
)) {
1251 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1256 _cleanup_free_
char *w
= NULL
;
1258 r
= extract_first_word(&p
, &w
, NULL
, 0);
1260 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1261 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1267 r
= dns_name_is_valid(w
);
1269 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1270 "%s is not a valid domain name, ignoring.", w
);
1274 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1278 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1288 int config_parse_ntp(
1290 const char *filename
,
1292 const char *section
,
1293 unsigned section_line
,
1307 if (isempty(rvalue
)) {
1313 _cleanup_free_
char *w
= NULL
;
1315 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1319 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1320 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1326 r
= dns_name_is_valid_or_address(w
);
1328 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1329 "%s is not a valid domain name or IP address, ignoring.", w
);
1333 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1334 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1335 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1336 MAX_NTP_SERVERS
, w
);
1340 r
= strv_consume(l
, TAKE_PTR(w
));
1348 int config_parse_required_for_online(
1350 const char *filename
,
1352 const char *section
,
1353 unsigned section_line
,
1360 Network
*network
= data
;
1361 LinkOperationalStateRange range
;
1362 bool required
= true;
1365 if (isempty(rvalue
)) {
1366 network
->required_for_online
= true;
1367 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1371 r
= parse_operational_state_range(rvalue
, &range
);
1373 r
= parse_boolean(rvalue
);
1375 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1376 "Failed to parse %s= setting, ignoring assignment: %s",
1382 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1385 network
->required_for_online
= required
;
1386 network
->required_operstate_for_online
= range
;
1391 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1392 "Failed to parse KeepConfiguration= setting");
1394 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1395 [KEEP_CONFIGURATION_NO
] = "no",
1396 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1397 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1398 [KEEP_CONFIGURATION_STATIC
] = "static",
1399 [KEEP_CONFIGURATION_YES
] = "yes",
1402 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);