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_assign_prefix
= true,
425 .dhcp_server_emit
[SD_DHCP_LEASE_DNS
].emit
= true,
426 .dhcp_server_emit
[SD_DHCP_LEASE_NTP
].emit
= true,
427 .dhcp_server_emit
[SD_DHCP_LEASE_SIP
].emit
= true,
429 .dhcp_server_emit_router
= true,
430 .dhcp_server_emit_timezone
= true,
432 .router_prefix_subnet_id
= -1,
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_request_options
);
674 set_free(network
->dhcp6_request_options
);
676 free(network
->dhcp6_mudurl
);
677 strv_free(network
->dhcp6_user_class
);
678 strv_free(network
->dhcp6_vendor_class
);
680 if (network
->dhcp_acd
)
681 sd_ipv4acd_unref(network
->dhcp_acd
);
683 strv_free(network
->ntp
);
685 ordered_set_free_free(network
->search_domains
);
686 ordered_set_free_free(network
->route_domains
);
687 strv_free(network
->bind_carrier
);
689 ordered_set_free_free(network
->router_search_domains
);
690 free(network
->router_dns
);
691 set_free_free(network
->ndisc_deny_listed_prefix
);
693 free(network
->bridge_name
);
694 free(network
->bond_name
);
695 free(network
->vrf_name
);
696 hashmap_free_free_key(network
->stacked_netdev_names
);
697 netdev_unref(network
->bridge
);
698 netdev_unref(network
->bond
);
699 netdev_unref(network
->vrf
);
700 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
702 while ((route
= network
->static_routes
))
705 while ((nexthop
= network
->static_nexthops
))
706 nexthop_free(nexthop
);
708 while ((address
= network
->static_addresses
))
709 address_free(address
);
711 while ((fdb_entry
= network
->static_fdb_entries
))
712 fdb_entry_free(fdb_entry
);
714 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
715 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
717 while ((neighbor
= network
->neighbors
))
718 neighbor_free(neighbor
);
720 while ((label
= network
->address_labels
))
721 address_label_free(label
);
723 while ((prefix
= network
->static_prefixes
))
726 while ((route_prefix
= network
->static_route_prefixes
))
727 route_prefix_free(route_prefix
);
729 while ((rule
= network
->rules
))
730 routing_policy_rule_free(rule
);
732 hashmap_free(network
->addresses_by_section
);
733 hashmap_free(network
->routes_by_section
);
734 hashmap_free(network
->nexthops_by_section
);
735 hashmap_free(network
->fdb_entries_by_section
);
736 hashmap_free(network
->neighbors_by_section
);
737 hashmap_free(network
->address_labels_by_section
);
738 hashmap_free(network
->prefixes_by_section
);
739 hashmap_free(network
->route_prefixes_by_section
);
740 hashmap_free(network
->rules_by_section
);
741 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
742 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
744 if (network
->manager
&&
745 network
->manager
->duids_requesting_uuid
)
746 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
750 free(network
->dhcp_server_timezone
);
752 for (sd_dhcp_lease_server_type t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
753 free(network
->dhcp_server_emit
[t
].addresses
);
755 set_free_free(network
->dnssec_negative_trust_anchors
);
757 free(network
->lldp_mud
);
759 ordered_hashmap_free(network
->dhcp_client_send_options
);
760 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
761 ordered_hashmap_free(network
->dhcp_server_send_options
);
762 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
763 ordered_hashmap_free(network
->ipv6_tokens
);
764 ordered_hashmap_free(network
->dhcp6_client_send_options
);
765 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
767 return mfree(network
);
770 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
772 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
779 network
= ordered_hashmap_get(manager
->networks
, name
);
788 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
789 const char *ifname
, char * const *alternative_names
, const char *driver
,
790 const struct ether_addr
*mac
, const struct ether_addr
*permanent_mac
,
791 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
799 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
800 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
801 network
->match_path
, network
->match_driver
,
802 network
->match_type
, network
->match_name
, network
->match_property
,
803 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
804 device
, mac
, permanent_mac
, driver
, iftype
,
805 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
806 if (network
->match_name
&& device
) {
808 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
810 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
811 (void) safe_atou8(attr
, &name_assign_type
);
813 if (name_assign_type
== NET_NAME_ENUM
)
814 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
815 ifname
, network
->filename
);
817 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
819 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
830 int network_apply(Network
*network
, Link
*link
) {
834 link
->network
= network_ref(network
);
836 if (network
->n_dns
> 0 ||
837 !strv_isempty(network
->ntp
) ||
838 !ordered_set_isempty(network
->search_domains
) ||
839 !ordered_set_isempty(network
->route_domains
))
845 bool network_has_static_ipv6_configurations(Network
*network
) {
853 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
854 if (address
->family
== AF_INET6
)
857 LIST_FOREACH(routes
, route
, network
->static_routes
)
858 if (route
->family
== AF_INET6
)
861 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
862 if (fdb
->family
== AF_INET6
)
865 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
866 if (neighbor
->family
== AF_INET6
)
869 if (!LIST_IS_EMPTY(network
->address_labels
))
872 if (!LIST_IS_EMPTY(network
->static_prefixes
))
878 int config_parse_stacked_netdev(const char *unit
,
879 const char *filename
,
882 unsigned section_line
,
888 _cleanup_free_
char *name
= NULL
;
889 NetDevKind kind
= ltype
;
898 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
899 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
900 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
903 if (!ifname_valid(rvalue
)) {
904 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
905 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
909 name
= strdup(rvalue
);
913 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
917 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
919 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
920 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
922 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
923 "NetDev '%s' specified twice, ignoring.", name
);
930 int config_parse_domains(
932 const char *filename
,
935 unsigned section_line
,
950 if (isempty(rvalue
)) {
951 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
952 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
958 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
962 r
= extract_first_word(&p
, &w
, NULL
, 0);
964 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
965 "Failed to extract search or route domain, ignoring: %s", rvalue
);
971 is_route
= w
[0] == '~';
972 domain
= is_route
? w
+ 1 : w
;
974 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
975 /* If the root domain appears as is, or the special token "*" is found, we'll
976 * consider this as routing domain, unconditionally. */
978 domain
= "."; /* make sure we don't allow empty strings, thus write the root
981 r
= dns_name_normalize(domain
, 0, &normalized
);
983 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
984 "'%s' is not a valid domain name, ignoring.", domain
);
990 if (is_localhost(domain
)) {
991 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
992 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
998 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
999 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
1003 r
= ordered_set_put_strdup(*set
, domain
);
1011 int config_parse_ipv6token(
1013 const char *filename
,
1015 const char *section
,
1016 unsigned section_line
,
1023 union in_addr_union buffer
;
1024 struct in6_addr
*token
= data
;
1032 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
1034 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1035 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1039 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1040 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1041 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1045 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1046 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1047 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1051 *token
= buffer
.in6
;
1056 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1057 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1058 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1059 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1062 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1063 IPV6_PRIVACY_EXTENSIONS_YES
);
1065 int config_parse_ipv6_privacy_extensions(
1067 const char *filename
,
1069 const char *section
,
1070 unsigned section_line
,
1077 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1082 assert(ipv6_privacy_extensions
);
1084 s
= ipv6_privacy_extensions_from_string(rvalue
);
1086 if (streq(rvalue
, "kernel"))
1087 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1089 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1090 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1095 *ipv6_privacy_extensions
= s
;
1100 int config_parse_hostname(
1102 const char *filename
,
1104 const char *section
,
1105 unsigned section_line
,
1112 _cleanup_free_
char *hn
= NULL
;
1113 char **hostname
= data
;
1120 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1124 if (!hostname_is_valid(hn
, false)) {
1125 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1126 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1130 r
= dns_name_is_valid(hn
);
1132 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1133 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1137 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1138 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1142 return free_and_replace(*hostname
, hn
);
1145 int config_parse_timezone(
1147 const char *filename
,
1149 const char *section
,
1150 unsigned section_line
,
1157 _cleanup_free_
char *tz
= NULL
;
1158 char **datap
= data
;
1165 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1169 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1170 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1171 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1175 return free_and_replace(*datap
, tz
);
1178 int config_parse_dns(
1180 const char *filename
,
1182 const char *section
,
1183 unsigned section_line
,
1190 Network
*n
= userdata
;
1198 _cleanup_free_
char *w
= NULL
;
1199 union in_addr_union a
;
1200 struct in_addr_data
*m
;
1203 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1207 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1208 "Invalid syntax, ignoring: %s", rvalue
);
1214 r
= in_addr_from_string_auto(w
, &family
, &a
);
1216 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1217 "Failed to parse dns server address, ignoring: %s", w
);
1221 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1225 m
[n
->n_dns
++] = (struct in_addr_data
) {
1236 int config_parse_dnssec_negative_trust_anchors(
1238 const char *filename
,
1240 const char *section
,
1241 unsigned section_line
,
1248 const char *p
= rvalue
;
1256 if (isempty(rvalue
)) {
1257 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1262 _cleanup_free_
char *w
= NULL
;
1264 r
= extract_first_word(&p
, &w
, NULL
, 0);
1266 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1267 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1273 r
= dns_name_is_valid(w
);
1275 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1276 "%s is not a valid domain name, ignoring.", w
);
1280 r
= set_ensure_consume(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
, TAKE_PTR(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
);
1404 static const char* const ipv6_link_local_address_gen_mode_table
[_IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX
] = {
1405 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64
] = "eui64",
1406 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
] = "none",
1407 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
] = "stable-privacy",
1408 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM
] = "random",
1411 DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode
, IPv6LinkLocalAddressGenMode
);
1412 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");