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 "networkd-sriov.h"
20 #include "parse-util.h"
21 #include "path-lookup.h"
23 #include "socket-util.h"
24 #include "stat-util.h"
25 #include "string-table.h"
26 #include "string-util.h"
31 /* Let's assume that anything above this number is a user misconfiguration. */
32 #define MAX_NTP_SERVERS 128
34 /* Set defaults following RFC7844 */
35 void network_apply_anonymize_if_set(Network
*network
) {
36 if (!network
->dhcp_anonymize
)
39 SHOULD NOT send the Host Name option */
40 network
->dhcp_send_hostname
= false;
41 /* RFC7844 section 3.:
42 MAY contain the Client Identifier option
44 clients MUST use client identifiers based solely
45 on the link-layer address */
46 /* NOTE: Using MAC, as it does not reveal extra information,
47 * and some servers might not answer if this option is not sent */
48 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
50 SHOULD NOT use the Vendor Class Identifier option */
51 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
52 /* RFC7844 section 3.6.:
53 The client intending to protect its privacy SHOULD only request a
54 minimal number of options in the PRL and SHOULD also randomly shuffle
55 the ordering of option codes in the PRL. If this random ordering
56 cannot be implemented, the client MAY order the option codes in the
57 PRL by option code number (lowest to highest).
59 /* NOTE: dhcp_use_mtu is false by default,
60 * though it was not initiallized to any value in network_load_one.
61 * Maybe there should be another var called *send*?
62 * (to use the MTU sent by the server but to do not send
63 * the option in the PRL). */
64 network
->dhcp_use_mtu
= false;
65 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
66 * but this is needed to use them. */
67 network
->dhcp_use_routes
= true;
68 /* RFC7844 section 3.6.
69 * same comments as previous option */
70 network
->dhcp_use_timezone
= false;
73 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
74 const char *kind_string
;
78 /* For test-networkd-conf, the check must be earlier than the assertions. */
83 assert(network
->manager
);
84 assert(network
->filename
);
87 if (kind
== _NETDEV_KIND_TUNNEL
)
88 kind_string
= "tunnel";
90 kind_string
= netdev_kind_to_string(kind
);
92 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
93 "%s: Invalid NetDev kind of %s, ignoring assignment.",
94 network
->filename
, name
);
97 r
= netdev_get(network
->manager
, name
, &netdev
);
99 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
100 network
->filename
, name
);
102 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
109 NETDEV_KIND_IP6GRETAP
,
113 NETDEV_KIND_ERSPAN
)))
114 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
115 "%s: NetDev %s is not a %s, ignoring assignment",
116 network
->filename
, name
, kind_string
);
118 *ret_netdev
= netdev_ref(netdev
);
122 static int network_resolve_stacked_netdevs(Network
*network
) {
129 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
130 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
132 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
136 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
140 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
142 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
143 network
->filename
, (const char *) name
);
151 int network_verify(Network
*network
) {
152 RoutePrefix
*route_prefix
, *route_prefix_next
;
153 RoutingPolicyRule
*rule
, *rule_next
;
154 Neighbor
*neighbor
, *neighbor_next
;
155 AddressLabel
*label
, *label_next
;
156 NextHop
*nexthop
, *nextnop_next
;
157 Address
*address
, *address_next
;
158 Prefix
*prefix
, *prefix_next
;
159 Route
*route
, *route_next
;
160 FdbEntry
*fdb
, *fdb_next
;
166 assert(network
->filename
);
168 if (set_isempty(network
->match_mac
) && set_isempty(network
->match_permanent_mac
) &&
169 strv_isempty(network
->match_path
) && strv_isempty(network
->match_driver
) &&
170 strv_isempty(network
->match_type
) && strv_isempty(network
->match_name
) &&
171 strv_isempty(network
->match_property
) && strv_isempty(network
->match_wlan_iftype
) &&
172 strv_isempty(network
->match_ssid
) && !network
->conditions
)
173 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
174 "%s: No valid settings found in the [Match] section, ignoring file. "
175 "To match all interfaces, add Name=* in the [Match] section.",
178 /* skip out early if configuration does not match the environment */
179 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
180 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
181 "%s: Conditions in the file do not match the system environment, skipping.",
184 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
185 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
186 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
187 (void) network_resolve_stacked_netdevs(network
);
189 /* Free unnecessary entries. */
190 network
->bond_name
= mfree(network
->bond_name
);
191 network
->bridge_name
= mfree(network
->bridge_name
);
192 network
->vrf_name
= mfree(network
->vrf_name
);
193 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
196 /* Bonding slave does not support addressing. */
197 if (network
->ipv6_accept_ra
> 0) {
198 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
200 network
->ipv6_accept_ra
= 0;
202 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
203 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
205 network
->link_local
= ADDRESS_FAMILY_NO
;
207 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
208 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
210 network
->dhcp
= ADDRESS_FAMILY_NO
;
212 if (network
->dhcp_server
) {
213 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
215 network
->dhcp_server
= false;
217 if (network
->n_static_addresses
> 0) {
218 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
220 while ((address
= network
->static_addresses
))
221 address_free(address
);
223 if (network
->n_static_routes
> 0) {
224 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
226 while ((route
= network
->static_routes
))
231 if (network
->link_local
< 0)
232 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
234 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
235 if (network
->ipv6_accept_ra
> 0) {
236 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
237 "Disabling IPv6AcceptRA=.", network
->filename
);
238 network
->ipv6_accept_ra
= false;
241 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
242 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
243 "Disabling DHCPv6 client.", network
->filename
);
244 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
247 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
248 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
249 "Disabling IPv6PrefixDelegation=.", network
->filename
);
250 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
254 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
255 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
256 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
257 "Disabling the fallback assignment.", network
->filename
);
258 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
261 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
262 network
->ipv6_accept_ra
= false;
264 /* IPMasquerade=yes implies IPForward=yes */
265 if (network
->ip_masquerade
)
266 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
268 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
269 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
270 "Disabling UseMTU=.", network
->filename
);
271 network
->dhcp_use_mtu
= false;
274 if (network
->dhcp_use_gateway
< 0)
275 network
->dhcp_use_gateway
= network
->dhcp_use_routes
;
277 if (network
->ignore_carrier_loss
< 0)
278 network
->ignore_carrier_loss
= network
->configure_without_carrier
;
280 if (network
->dhcp_critical
>= 0) {
281 if (network
->keep_configuration
>= 0)
282 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
283 "Ignoring CriticalConnection=.", network
->filename
);
284 else if (network
->dhcp_critical
)
285 /* CriticalConnection=yes also preserve foreign static configurations. */
286 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
288 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
291 if (network
->keep_configuration
< 0)
292 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
294 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
295 if (address_section_verify(address
) < 0)
296 address_free(address
);
298 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
299 if (route_section_verify(route
, network
) < 0)
302 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
303 if (nexthop_section_verify(nexthop
) < 0)
304 nexthop_free(nexthop
);
306 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
307 if (section_is_invalid(fdb
->section
))
310 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
311 if (neighbor_section_verify(neighbor
) < 0)
312 neighbor_free(neighbor
);
314 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
315 if (section_is_invalid(label
->section
))
316 address_label_free(label
);
318 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
319 if (section_is_invalid(prefix
->section
))
322 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
323 if (section_is_invalid(route_prefix
->section
))
324 route_prefix_free(route_prefix
);
326 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
327 if (routing_policy_rule_section_verify(rule
) < 0)
328 routing_policy_rule_free(rule
);
330 bool has_root
= false, has_clsact
= false;
331 ORDERED_HASHMAP_FOREACH(tc
, network
->tc_by_section
, i
)
332 if (traffic_control_section_verify(tc
, &has_root
, &has_clsact
) < 0)
333 traffic_control_free(tc
);
335 ORDERED_HASHMAP_FOREACH(sr_iov
, network
->sr_iov_by_section
, i
)
336 if (sr_iov_section_verify(sr_iov
) < 0)
342 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
343 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
344 _cleanup_(network_unrefp
) Network
*network
= NULL
;
345 _cleanup_fclose_
FILE *file
= NULL
;
346 const char *dropin_dirname
;
353 file
= fopen(filename
, "re");
361 if (null_or_empty_fd(fileno(file
))) {
362 log_debug("Skipping empty file: %s", filename
);
366 fname
= strdup(filename
);
370 name
= strdup(basename(filename
));
374 d
= strrchr(name
, '.');
380 dropin_dirname
= strjoina(name
, ".network.d");
382 network
= new(Network
, 1);
386 *network
= (Network
) {
387 .filename
= TAKE_PTR(fname
),
388 .name
= TAKE_PTR(name
),
393 .required_for_online
= true,
394 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
395 .dhcp
= ADDRESS_FAMILY_NO
,
397 .dhcp_use_ntp
= true,
398 .dhcp_use_sip
= true,
399 .dhcp_use_dns
= true,
400 .dhcp_use_hostname
= true,
401 .dhcp_use_routes
= true,
402 .dhcp_use_gateway
= -1,
403 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
404 .dhcp_send_hostname
= true,
405 .dhcp_send_release
= true,
406 /* To enable/disable RFC7844 Anonymity Profiles */
407 .dhcp_anonymize
= false,
408 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
409 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
410 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
411 .dhcp_route_table
= RT_TABLE_MAIN
,
412 .dhcp_route_table_set
= false,
413 /* NOTE: from man: UseMTU=... Defaults to false*/
414 .dhcp_use_mtu
= false,
415 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
416 .dhcp_use_timezone
= false,
417 .rapid_commit
= true,
419 .dhcp6_route_metric
= DHCP_ROUTE_METRIC
,
420 .dhcp6_use_ntp
= true,
421 .dhcp6_use_dns
= true,
423 .dhcp6_pd_subnet_id
= -1,
424 .dhcp6_pd_assign
= true,
426 .dhcp_server_emit
[SD_DHCP_LEASE_DNS
].emit
= true,
427 .dhcp_server_emit
[SD_DHCP_LEASE_NTP
].emit
= true,
428 .dhcp_server_emit
[SD_DHCP_LEASE_SIP
].emit
= true,
430 .dhcp_server_emit_router
= true,
431 .dhcp_server_emit_timezone
= true,
433 .router_emit_dns
= true,
434 .router_emit_domains
= true,
439 .allow_port_to_be_root
= -1,
441 .multicast_flood
= -1,
442 .multicast_to_unicast
= -1,
443 .neighbor_suppression
= -1,
445 .bridge_proxy_arp
= -1,
446 .bridge_proxy_arp_wifi
= -1,
447 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
448 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
450 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
452 .dns_default_route
= -1,
453 .llmnr
= RESOLVE_SUPPORT_YES
,
454 .mdns
= RESOLVE_SUPPORT_NO
,
455 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
456 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
458 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
459 .link_local
= _ADDRESS_FAMILY_INVALID
,
460 .ipv6ll_address_gen_mode
= _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID
,
462 .ipv4_accept_local
= -1,
464 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
465 .ipv6_accept_ra
= -1,
466 .ipv6_dad_transmits
= -1,
467 .ipv6_hop_limit
= -1,
468 .ipv6_proxy_ndp
= -1,
469 .duid
.type
= _DUID_TYPE_INVALID
,
474 .ipv6_accept_ra_use_dns
= true,
475 .ipv6_accept_ra_use_autonomous_prefix
= true,
476 .ipv6_accept_ra_use_onlink_prefix
= true,
477 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
478 .ipv6_accept_ra_route_table_set
= false,
479 .ipv6_accept_ra_start_dhcp6_client
= true,
481 .configure_without_carrier
= false,
482 .ignore_carrier_loss
= -1,
483 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
484 .can_triple_sampling
= -1,
485 .can_termination
= -1,
486 .ip_service_type
= -1,
489 r
= config_parse_many(
490 filename
, NETWORK_DIRS
, dropin_dirname
,
498 "RoutingPolicyRule\0"
501 "DHCP\0" /* compat */
506 "IPv6NDPProxyAddress\0"
510 "IPv6PrefixDelegation\0"
514 "TrafficControlQueueingDiscipline\0"
520 "DeficitRoundRobinScheduler\0"
521 "DeficitRoundRobinSchedulerClass\0"
522 "EnhancedTransmissionSelection\0"
524 "FairQueueingControlledDelay\0"
525 "GenericRandomEarlyDetection\0"
526 "HeavyHitterFilter\0"
527 "HierarchyTokenBucket\0"
528 "HierarchyTokenBucketClass\0"
534 "QuickFairQueueing\0"
535 "QuickFairQueueingClass\0"
536 "StochasticFairBlue\0"
537 "StochasticFairnessQueueing\0"
538 "TokenBucketFilter\0"
539 "TrivialLinkEqualizer\0",
540 config_item_perf_lookup
, network_network_gperf_lookup
,
543 &network
->timestamp
);
547 network_apply_anonymize_if_set(network
);
549 r
= network_add_ipv4ll_route(network
);
551 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
553 r
= network_add_default_route_on_device(network
);
555 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
558 if (network_verify(network
) < 0)
559 /* Ignore .network files that do not match the conditions. */
562 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
566 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
574 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
575 _cleanup_strv_free_
char **files
= NULL
;
581 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
583 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
585 return log_error_errno(r
, "Failed to enumerate network files: %m");
587 STRV_FOREACH(f
, files
) {
588 r
= network_load_one(manager
, networks
, *f
);
590 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
596 int network_reload(Manager
*manager
) {
597 OrderedHashmap
*new_networks
= NULL
;
604 r
= network_load(manager
, &new_networks
);
608 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
609 r
= network_get_by_name(manager
, n
->name
, &old
);
611 continue; /* The .network file is new. */
613 if (n
->timestamp
!= old
->timestamp
)
614 continue; /* The .network file is modified. */
616 if (!streq(n
->filename
, old
->filename
))
619 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
627 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
628 manager
->networks
= new_networks
;
633 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
638 static Network
*network_free(Network
*network
) {
639 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
640 RoutePrefix
*route_prefix
;
641 RoutingPolicyRule
*rule
;
653 free(network
->filename
);
655 set_free_free(network
->match_mac
);
656 set_free_free(network
->match_permanent_mac
);
657 strv_free(network
->match_path
);
658 strv_free(network
->match_driver
);
659 strv_free(network
->match_type
);
660 strv_free(network
->match_name
);
661 strv_free(network
->match_property
);
662 strv_free(network
->match_wlan_iftype
);
663 strv_free(network
->match_ssid
);
664 set_free_free(network
->match_bssid
);
665 condition_free_list(network
->conditions
);
667 free(network
->description
);
668 free(network
->dhcp_vendor_class_identifier
);
669 free(network
->dhcp_mudurl
);
670 strv_free(network
->dhcp_user_class
);
671 free(network
->dhcp_hostname
);
672 set_free(network
->dhcp_deny_listed_ip
);
673 set_free(network
->dhcp_allow_listed_ip
);
674 set_free(network
->dhcp_request_options
);
675 set_free(network
->dhcp6_request_options
);
677 free(network
->dhcp6_mudurl
);
678 strv_free(network
->dhcp6_user_class
);
679 strv_free(network
->dhcp6_vendor_class
);
681 if (network
->dhcp_acd
)
682 sd_ipv4acd_unref(network
->dhcp_acd
);
684 strv_free(network
->ntp
);
685 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
686 in_addr_full_free(network
->dns
[i
]);
688 ordered_set_free_free(network
->search_domains
);
689 ordered_set_free_free(network
->route_domains
);
690 strv_free(network
->bind_carrier
);
692 ordered_set_free_free(network
->router_search_domains
);
693 free(network
->router_dns
);
694 set_free_free(network
->ndisc_deny_listed_prefix
);
696 free(network
->bridge_name
);
697 free(network
->bond_name
);
698 free(network
->vrf_name
);
699 hashmap_free_free_key(network
->stacked_netdev_names
);
700 netdev_unref(network
->bridge
);
701 netdev_unref(network
->bond
);
702 netdev_unref(network
->vrf
);
703 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
705 while ((route
= network
->static_routes
))
708 while ((nexthop
= network
->static_nexthops
))
709 nexthop_free(nexthop
);
711 while ((address
= network
->static_addresses
))
712 address_free(address
);
714 while ((fdb_entry
= network
->static_fdb_entries
))
715 fdb_entry_free(fdb_entry
);
717 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
718 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
720 while ((neighbor
= network
->neighbors
))
721 neighbor_free(neighbor
);
723 while ((label
= network
->address_labels
))
724 address_label_free(label
);
726 while ((prefix
= network
->static_prefixes
))
729 while ((route_prefix
= network
->static_route_prefixes
))
730 route_prefix_free(route_prefix
);
732 while ((rule
= network
->rules
))
733 routing_policy_rule_free(rule
);
735 hashmap_free(network
->addresses_by_section
);
736 hashmap_free(network
->routes_by_section
);
737 hashmap_free(network
->nexthops_by_section
);
738 hashmap_free(network
->fdb_entries_by_section
);
739 hashmap_free(network
->neighbors_by_section
);
740 hashmap_free(network
->address_labels_by_section
);
741 hashmap_free(network
->prefixes_by_section
);
742 hashmap_free(network
->route_prefixes_by_section
);
743 hashmap_free(network
->rules_by_section
);
744 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
745 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
747 if (network
->manager
&&
748 network
->manager
->duids_requesting_uuid
)
749 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
753 free(network
->dhcp_server_timezone
);
755 for (sd_dhcp_lease_server_type t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
756 free(network
->dhcp_server_emit
[t
].addresses
);
758 set_free_free(network
->dnssec_negative_trust_anchors
);
760 free(network
->lldp_mud
);
762 ordered_hashmap_free(network
->dhcp_client_send_options
);
763 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
764 ordered_hashmap_free(network
->dhcp_server_send_options
);
765 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
766 ordered_set_free(network
->ipv6_tokens
);
767 ordered_hashmap_free(network
->dhcp6_client_send_options
);
768 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
770 return mfree(network
);
773 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
775 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
782 network
= ordered_hashmap_get(manager
->networks
, name
);
791 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
792 const char *ifname
, char * const *alternative_names
, const char *driver
,
793 const struct ether_addr
*mac
, const struct ether_addr
*permanent_mac
,
794 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
802 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
803 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
804 network
->match_path
, network
->match_driver
,
805 network
->match_type
, network
->match_name
, network
->match_property
,
806 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
807 device
, mac
, permanent_mac
, driver
, iftype
,
808 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
809 if (network
->match_name
&& device
) {
811 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
813 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
814 (void) safe_atou8(attr
, &name_assign_type
);
816 if (name_assign_type
== NET_NAME_ENUM
)
817 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
818 ifname
, network
->filename
);
820 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
822 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
833 int network_apply(Network
*network
, Link
*link
) {
837 link
->network
= network_ref(network
);
839 if (network
->n_dns
> 0 ||
840 !strv_isempty(network
->ntp
) ||
841 !ordered_set_isempty(network
->search_domains
) ||
842 !ordered_set_isempty(network
->route_domains
))
848 bool network_has_static_ipv6_configurations(Network
*network
) {
856 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
857 if (address
->family
== AF_INET6
)
860 LIST_FOREACH(routes
, route
, network
->static_routes
)
861 if (route
->family
== AF_INET6
)
864 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
865 if (fdb
->family
== AF_INET6
)
868 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
869 if (neighbor
->family
== AF_INET6
)
872 if (!LIST_IS_EMPTY(network
->address_labels
))
875 if (!LIST_IS_EMPTY(network
->static_prefixes
))
881 int config_parse_stacked_netdev(const char *unit
,
882 const char *filename
,
885 unsigned section_line
,
891 _cleanup_free_
char *name
= NULL
;
892 NetDevKind kind
= ltype
;
901 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
902 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
903 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
906 if (!ifname_valid(rvalue
)) {
907 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
908 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
912 name
= strdup(rvalue
);
916 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
920 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
922 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
923 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
925 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
926 "NetDev '%s' specified twice, ignoring.", name
);
933 int config_parse_domains(
935 const char *filename
,
938 unsigned section_line
,
952 if (isempty(rvalue
)) {
953 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
954 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
958 for (const char *p
= rvalue
;;) {
959 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
963 r
= extract_first_word(&p
, &w
, NULL
, 0);
967 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
968 "Failed to extract search or route domain, ignoring: %s", rvalue
);
974 is_route
= w
[0] == '~';
975 domain
= is_route
? w
+ 1 : w
;
977 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
978 /* If the root domain appears as is, or the special token "*" is found, we'll
979 * consider this as routing domain, unconditionally. */
981 domain
= "."; /* make sure we don't allow empty strings, thus write the root
984 r
= dns_name_normalize(domain
, 0, &normalized
);
986 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
987 "'%s' is not a valid domain name, ignoring.", domain
);
993 if (is_localhost(domain
)) {
994 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
995 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
1001 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
1002 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
1006 r
= ordered_set_put_strdup(*set
, domain
);
1012 int config_parse_ipv6token(
1014 const char *filename
,
1016 const char *section
,
1017 unsigned section_line
,
1024 union in_addr_union buffer
;
1025 struct in6_addr
*token
= data
;
1033 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
1035 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1036 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1040 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1041 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1042 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1046 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1047 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1048 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1052 *token
= buffer
.in6
;
1057 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1058 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1059 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1060 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1063 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1064 IPV6_PRIVACY_EXTENSIONS_YES
);
1066 int config_parse_ipv6_privacy_extensions(
1068 const char *filename
,
1070 const char *section
,
1071 unsigned section_line
,
1078 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1083 assert(ipv6_privacy_extensions
);
1085 s
= ipv6_privacy_extensions_from_string(rvalue
);
1087 if (streq(rvalue
, "kernel"))
1088 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1090 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1091 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1096 *ipv6_privacy_extensions
= s
;
1101 int config_parse_hostname(
1103 const char *filename
,
1105 const char *section
,
1106 unsigned section_line
,
1113 _cleanup_free_
char *hn
= NULL
;
1114 char **hostname
= data
;
1121 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1125 if (!hostname_is_valid(hn
, false)) {
1126 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1127 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1131 r
= dns_name_is_valid(hn
);
1133 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1134 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1138 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1139 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1143 return free_and_replace(*hostname
, hn
);
1146 int config_parse_timezone(
1148 const char *filename
,
1150 const char *section
,
1151 unsigned section_line
,
1158 _cleanup_free_
char *tz
= NULL
;
1159 char **datap
= data
;
1166 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1170 if (!timezone_is_valid(tz
, LOG_WARNING
)) {
1171 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1172 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1176 return free_and_replace(*datap
, tz
);
1179 int config_parse_dns(
1181 const char *filename
,
1183 const char *section
,
1184 unsigned section_line
,
1191 Network
*n
= userdata
;
1198 if (isempty(rvalue
)) {
1199 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
1200 in_addr_full_free(n
->dns
[i
]);
1201 n
->dns
= mfree(n
->dns
);
1206 for (const char *p
= rvalue
;;) {
1207 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
1208 _cleanup_free_
char *w
= NULL
;
1209 struct in_addr_full
**m
;
1211 r
= extract_first_word(&p
, &w
, NULL
, 0);
1215 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1216 "Invalid syntax, ignoring: %s", rvalue
);
1222 r
= in_addr_full_new_from_string(w
, &dns
);
1224 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1225 "Failed to parse dns server address, ignoring: %s", w
);
1229 if (IN_SET(dns
->port
, 53, 853))
1232 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
1236 m
[n
->n_dns
++] = TAKE_PTR(dns
);
1241 int config_parse_dnssec_negative_trust_anchors(
1243 const char *filename
,
1245 const char *section
,
1246 unsigned section_line
,
1260 if (isempty(rvalue
)) {
1261 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1265 for (const char *p
= rvalue
;;) {
1266 _cleanup_free_
char *w
= NULL
;
1268 r
= extract_first_word(&p
, &w
, NULL
, 0);
1272 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1273 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1279 r
= dns_name_is_valid(w
);
1281 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1282 "%s is not a valid domain name, ignoring.", w
);
1286 r
= set_ensure_consume(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
, TAKE_PTR(w
));
1292 int config_parse_ntp(
1294 const char *filename
,
1296 const char *section
,
1297 unsigned section_line
,
1311 if (isempty(rvalue
)) {
1316 for (const char *p
= rvalue
;;) {
1317 _cleanup_free_
char *w
= NULL
;
1319 r
= extract_first_word(&p
, &w
, NULL
, 0);
1323 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1324 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1330 r
= dns_name_is_valid_or_address(w
);
1332 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1333 "%s is not a valid domain name or IP address, ignoring.", w
);
1337 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1338 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1339 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1340 MAX_NTP_SERVERS
, w
);
1344 r
= strv_consume(l
, TAKE_PTR(w
));
1350 int config_parse_required_for_online(
1352 const char *filename
,
1354 const char *section
,
1355 unsigned section_line
,
1362 Network
*network
= data
;
1363 LinkOperationalStateRange range
;
1364 bool required
= true;
1367 if (isempty(rvalue
)) {
1368 network
->required_for_online
= true;
1369 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1373 r
= parse_operational_state_range(rvalue
, &range
);
1375 r
= parse_boolean(rvalue
);
1377 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1378 "Failed to parse %s= setting, ignoring assignment: %s",
1384 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1387 network
->required_for_online
= required
;
1388 network
->required_operstate_for_online
= range
;
1393 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1394 "Failed to parse KeepConfiguration= setting");
1396 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1397 [KEEP_CONFIGURATION_NO
] = "no",
1398 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1399 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1400 [KEEP_CONFIGURATION_STATIC
] = "static",
1401 [KEEP_CONFIGURATION_YES
] = "yes",
1404 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1406 static const char* const ipv6_link_local_address_gen_mode_table
[_IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX
] = {
1407 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64
] = "eui64",
1408 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
] = "none",
1409 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
] = "stable-privacy",
1410 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM
] = "random",
1413 DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode
, IPv6LinkLocalAddressGenMode
);
1414 DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_link_local_address_gen_mode
, ipv6_link_local_address_gen_mode
, IPv6LinkLocalAddressGenMode
, "Failed to parse IPv6 link local address generation mode");