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 */
504 "DHCPv6PrefixDelegation\0"
507 "IPv6NDPProxyAddress\0"
511 "IPv6PrefixDelegation\0"
515 "TrafficControlQueueingDiscipline\0"
521 "DeficitRoundRobinScheduler\0"
522 "DeficitRoundRobinSchedulerClass\0"
523 "EnhancedTransmissionSelection\0"
525 "FairQueueingControlledDelay\0"
526 "GenericRandomEarlyDetection\0"
527 "HeavyHitterFilter\0"
528 "HierarchyTokenBucket\0"
529 "HierarchyTokenBucketClass\0"
535 "QuickFairQueueing\0"
536 "QuickFairQueueingClass\0"
537 "StochasticFairBlue\0"
538 "StochasticFairnessQueueing\0"
539 "TokenBucketFilter\0"
540 "TrivialLinkEqualizer\0",
541 config_item_perf_lookup
, network_network_gperf_lookup
,
544 &network
->timestamp
);
548 network_apply_anonymize_if_set(network
);
550 r
= network_add_ipv4ll_route(network
);
552 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
554 r
= network_add_default_route_on_device(network
);
556 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
559 if (network_verify(network
) < 0)
560 /* Ignore .network files that do not match the conditions. */
563 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
567 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
575 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
576 _cleanup_strv_free_
char **files
= NULL
;
582 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
584 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
586 return log_error_errno(r
, "Failed to enumerate network files: %m");
588 STRV_FOREACH(f
, files
) {
589 r
= network_load_one(manager
, networks
, *f
);
591 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
597 int network_reload(Manager
*manager
) {
598 OrderedHashmap
*new_networks
= NULL
;
605 r
= network_load(manager
, &new_networks
);
609 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
610 r
= network_get_by_name(manager
, n
->name
, &old
);
612 continue; /* The .network file is new. */
614 if (n
->timestamp
!= old
->timestamp
)
615 continue; /* The .network file is modified. */
617 if (!streq(n
->filename
, old
->filename
))
620 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
628 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
629 manager
->networks
= new_networks
;
634 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
639 static Network
*network_free(Network
*network
) {
640 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
641 RoutePrefix
*route_prefix
;
642 RoutingPolicyRule
*rule
;
654 free(network
->filename
);
656 set_free_free(network
->match_mac
);
657 set_free_free(network
->match_permanent_mac
);
658 strv_free(network
->match_path
);
659 strv_free(network
->match_driver
);
660 strv_free(network
->match_type
);
661 strv_free(network
->match_name
);
662 strv_free(network
->match_property
);
663 strv_free(network
->match_wlan_iftype
);
664 strv_free(network
->match_ssid
);
665 set_free_free(network
->match_bssid
);
666 condition_free_list(network
->conditions
);
668 free(network
->description
);
669 free(network
->dhcp_vendor_class_identifier
);
670 free(network
->dhcp_mudurl
);
671 strv_free(network
->dhcp_user_class
);
672 free(network
->dhcp_hostname
);
673 set_free(network
->dhcp_deny_listed_ip
);
674 set_free(network
->dhcp_allow_listed_ip
);
675 set_free(network
->dhcp_request_options
);
676 set_free(network
->dhcp6_request_options
);
678 free(network
->dhcp6_mudurl
);
679 strv_free(network
->dhcp6_user_class
);
680 strv_free(network
->dhcp6_vendor_class
);
682 if (network
->dhcp_acd
)
683 sd_ipv4acd_unref(network
->dhcp_acd
);
685 strv_free(network
->ntp
);
686 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
687 in_addr_full_free(network
->dns
[i
]);
689 ordered_set_free_free(network
->search_domains
);
690 ordered_set_free_free(network
->route_domains
);
691 strv_free(network
->bind_carrier
);
693 ordered_set_free_free(network
->router_search_domains
);
694 free(network
->router_dns
);
695 set_free_free(network
->ndisc_deny_listed_prefix
);
697 free(network
->bridge_name
);
698 free(network
->bond_name
);
699 free(network
->vrf_name
);
700 hashmap_free_free_key(network
->stacked_netdev_names
);
701 netdev_unref(network
->bridge
);
702 netdev_unref(network
->bond
);
703 netdev_unref(network
->vrf
);
704 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
706 while ((route
= network
->static_routes
))
709 while ((nexthop
= network
->static_nexthops
))
710 nexthop_free(nexthop
);
712 while ((address
= network
->static_addresses
))
713 address_free(address
);
715 while ((fdb_entry
= network
->static_fdb_entries
))
716 fdb_entry_free(fdb_entry
);
718 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
719 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
721 while ((neighbor
= network
->neighbors
))
722 neighbor_free(neighbor
);
724 while ((label
= network
->address_labels
))
725 address_label_free(label
);
727 while ((prefix
= network
->static_prefixes
))
730 while ((route_prefix
= network
->static_route_prefixes
))
731 route_prefix_free(route_prefix
);
733 while ((rule
= network
->rules
))
734 routing_policy_rule_free(rule
);
736 hashmap_free(network
->addresses_by_section
);
737 hashmap_free(network
->routes_by_section
);
738 hashmap_free(network
->nexthops_by_section
);
739 hashmap_free(network
->fdb_entries_by_section
);
740 hashmap_free(network
->neighbors_by_section
);
741 hashmap_free(network
->address_labels_by_section
);
742 hashmap_free(network
->prefixes_by_section
);
743 hashmap_free(network
->route_prefixes_by_section
);
744 hashmap_free(network
->rules_by_section
);
745 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
746 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
748 if (network
->manager
&&
749 network
->manager
->duids_requesting_uuid
)
750 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
754 free(network
->dhcp_server_timezone
);
756 for (sd_dhcp_lease_server_type t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
757 free(network
->dhcp_server_emit
[t
].addresses
);
759 set_free_free(network
->dnssec_negative_trust_anchors
);
761 free(network
->lldp_mud
);
763 ordered_hashmap_free(network
->dhcp_client_send_options
);
764 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
765 ordered_hashmap_free(network
->dhcp_server_send_options
);
766 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
767 ordered_set_free(network
->ipv6_tokens
);
768 ordered_hashmap_free(network
->dhcp6_client_send_options
);
769 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
771 return mfree(network
);
774 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
776 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
783 network
= ordered_hashmap_get(manager
->networks
, name
);
792 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
793 const char *ifname
, char * const *alternative_names
, const char *driver
,
794 const struct ether_addr
*mac
, const struct ether_addr
*permanent_mac
,
795 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
803 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
804 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
805 network
->match_path
, network
->match_driver
,
806 network
->match_type
, network
->match_name
, network
->match_property
,
807 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
808 device
, mac
, permanent_mac
, driver
, iftype
,
809 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
810 if (network
->match_name
&& device
) {
812 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
814 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
815 (void) safe_atou8(attr
, &name_assign_type
);
817 if (name_assign_type
== NET_NAME_ENUM
)
818 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
819 ifname
, network
->filename
);
821 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
823 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
834 int network_apply(Network
*network
, Link
*link
) {
838 link
->network
= network_ref(network
);
840 if (network
->n_dns
> 0 ||
841 !strv_isempty(network
->ntp
) ||
842 !ordered_set_isempty(network
->search_domains
) ||
843 !ordered_set_isempty(network
->route_domains
))
849 bool network_has_static_ipv6_configurations(Network
*network
) {
857 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
858 if (address
->family
== AF_INET6
)
861 LIST_FOREACH(routes
, route
, network
->static_routes
)
862 if (route
->family
== AF_INET6
)
865 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
866 if (fdb
->family
== AF_INET6
)
869 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
870 if (neighbor
->family
== AF_INET6
)
873 if (!LIST_IS_EMPTY(network
->address_labels
))
876 if (!LIST_IS_EMPTY(network
->static_prefixes
))
882 int config_parse_stacked_netdev(const char *unit
,
883 const char *filename
,
886 unsigned section_line
,
892 _cleanup_free_
char *name
= NULL
;
893 NetDevKind kind
= ltype
;
902 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
903 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
904 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
907 if (!ifname_valid(rvalue
)) {
908 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
909 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
913 name
= strdup(rvalue
);
917 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
921 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
923 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
924 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
926 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
927 "NetDev '%s' specified twice, ignoring.", name
);
934 int config_parse_domains(
936 const char *filename
,
939 unsigned section_line
,
953 if (isempty(rvalue
)) {
954 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
955 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
959 for (const char *p
= rvalue
;;) {
960 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
964 r
= extract_first_word(&p
, &w
, NULL
, 0);
968 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
969 "Failed to extract search or route domain, ignoring: %s", rvalue
);
975 is_route
= w
[0] == '~';
976 domain
= is_route
? w
+ 1 : w
;
978 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
979 /* If the root domain appears as is, or the special token "*" is found, we'll
980 * consider this as routing domain, unconditionally. */
982 domain
= "."; /* make sure we don't allow empty strings, thus write the root
985 r
= dns_name_normalize(domain
, 0, &normalized
);
987 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
988 "'%s' is not a valid domain name, ignoring.", domain
);
994 if (is_localhost(domain
)) {
995 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
996 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
1002 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
1003 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
1007 r
= ordered_set_put_strdup(*set
, domain
);
1013 int config_parse_ipv6token(
1015 const char *filename
,
1017 const char *section
,
1018 unsigned section_line
,
1025 union in_addr_union buffer
;
1026 struct in6_addr
*token
= data
;
1034 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
1036 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1037 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1041 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1042 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1043 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1047 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1048 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1049 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1053 *token
= buffer
.in6
;
1058 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1059 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1060 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1061 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1064 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1065 IPV6_PRIVACY_EXTENSIONS_YES
);
1067 int config_parse_ipv6_privacy_extensions(
1069 const char *filename
,
1071 const char *section
,
1072 unsigned section_line
,
1079 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1084 assert(ipv6_privacy_extensions
);
1086 s
= ipv6_privacy_extensions_from_string(rvalue
);
1088 if (streq(rvalue
, "kernel"))
1089 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1091 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1092 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1097 *ipv6_privacy_extensions
= s
;
1102 int config_parse_hostname(
1104 const char *filename
,
1106 const char *section
,
1107 unsigned section_line
,
1114 _cleanup_free_
char *hn
= NULL
;
1115 char **hostname
= data
;
1122 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1126 if (!hostname_is_valid(hn
, false)) {
1127 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1128 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1132 r
= dns_name_is_valid(hn
);
1134 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1135 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1139 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1140 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1144 return free_and_replace(*hostname
, hn
);
1147 int config_parse_timezone(
1149 const char *filename
,
1151 const char *section
,
1152 unsigned section_line
,
1159 _cleanup_free_
char *tz
= NULL
;
1160 char **datap
= data
;
1167 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1171 if (!timezone_is_valid(tz
, LOG_WARNING
)) {
1172 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1173 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1177 return free_and_replace(*datap
, tz
);
1180 int config_parse_dns(
1182 const char *filename
,
1184 const char *section
,
1185 unsigned section_line
,
1192 Network
*n
= userdata
;
1199 if (isempty(rvalue
)) {
1200 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
1201 in_addr_full_free(n
->dns
[i
]);
1202 n
->dns
= mfree(n
->dns
);
1207 for (const char *p
= rvalue
;;) {
1208 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
1209 _cleanup_free_
char *w
= NULL
;
1210 struct in_addr_full
**m
;
1212 r
= extract_first_word(&p
, &w
, NULL
, 0);
1216 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1217 "Invalid syntax, ignoring: %s", rvalue
);
1223 r
= in_addr_full_new_from_string(w
, &dns
);
1225 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1226 "Failed to parse dns server address, ignoring: %s", w
);
1230 if (IN_SET(dns
->port
, 53, 853))
1233 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
1237 m
[n
->n_dns
++] = TAKE_PTR(dns
);
1242 int config_parse_dnssec_negative_trust_anchors(
1244 const char *filename
,
1246 const char *section
,
1247 unsigned section_line
,
1261 if (isempty(rvalue
)) {
1262 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1266 for (const char *p
= rvalue
;;) {
1267 _cleanup_free_
char *w
= NULL
;
1269 r
= extract_first_word(&p
, &w
, NULL
, 0);
1273 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1274 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1280 r
= dns_name_is_valid(w
);
1282 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1283 "%s is not a valid domain name, ignoring.", w
);
1287 r
= set_ensure_consume(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
, TAKE_PTR(w
));
1293 int config_parse_ntp(
1295 const char *filename
,
1297 const char *section
,
1298 unsigned section_line
,
1312 if (isempty(rvalue
)) {
1317 for (const char *p
= rvalue
;;) {
1318 _cleanup_free_
char *w
= NULL
;
1320 r
= extract_first_word(&p
, &w
, NULL
, 0);
1324 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1325 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1331 r
= dns_name_is_valid_or_address(w
);
1333 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1334 "%s is not a valid domain name or IP address, ignoring.", w
);
1338 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1339 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1340 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1341 MAX_NTP_SERVERS
, w
);
1345 r
= strv_consume(l
, TAKE_PTR(w
));
1351 int config_parse_required_for_online(
1353 const char *filename
,
1355 const char *section
,
1356 unsigned section_line
,
1363 Network
*network
= data
;
1364 LinkOperationalStateRange range
;
1365 bool required
= true;
1368 if (isempty(rvalue
)) {
1369 network
->required_for_online
= true;
1370 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1374 r
= parse_operational_state_range(rvalue
, &range
);
1376 r
= parse_boolean(rvalue
);
1378 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1379 "Failed to parse %s= setting, ignoring assignment: %s",
1385 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1388 network
->required_for_online
= required
;
1389 network
->required_operstate_for_online
= range
;
1394 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1395 "Failed to parse KeepConfiguration= setting");
1397 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1398 [KEEP_CONFIGURATION_NO
] = "no",
1399 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1400 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1401 [KEEP_CONFIGURATION_STATIC
] = "static",
1402 [KEEP_CONFIGURATION_YES
] = "yes",
1405 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1407 static const char* const ipv6_link_local_address_gen_mode_table
[_IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX
] = {
1408 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64
] = "eui64",
1409 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
] = "none",
1410 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
] = "stable-privacy",
1411 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM
] = "random",
1414 DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode
, IPv6LinkLocalAddressGenMode
);
1415 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");