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_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
);
686 ordered_set_free_free(network
->search_domains
);
687 ordered_set_free_free(network
->route_domains
);
688 strv_free(network
->bind_carrier
);
690 ordered_set_free_free(network
->router_search_domains
);
691 free(network
->router_dns
);
692 set_free_free(network
->ndisc_deny_listed_prefix
);
694 free(network
->bridge_name
);
695 free(network
->bond_name
);
696 free(network
->vrf_name
);
697 hashmap_free_free_key(network
->stacked_netdev_names
);
698 netdev_unref(network
->bridge
);
699 netdev_unref(network
->bond
);
700 netdev_unref(network
->vrf
);
701 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
703 while ((route
= network
->static_routes
))
706 while ((nexthop
= network
->static_nexthops
))
707 nexthop_free(nexthop
);
709 while ((address
= network
->static_addresses
))
710 address_free(address
);
712 while ((fdb_entry
= network
->static_fdb_entries
))
713 fdb_entry_free(fdb_entry
);
715 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
716 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
718 while ((neighbor
= network
->neighbors
))
719 neighbor_free(neighbor
);
721 while ((label
= network
->address_labels
))
722 address_label_free(label
);
724 while ((prefix
= network
->static_prefixes
))
727 while ((route_prefix
= network
->static_route_prefixes
))
728 route_prefix_free(route_prefix
);
730 while ((rule
= network
->rules
))
731 routing_policy_rule_free(rule
);
733 hashmap_free(network
->addresses_by_section
);
734 hashmap_free(network
->routes_by_section
);
735 hashmap_free(network
->nexthops_by_section
);
736 hashmap_free(network
->fdb_entries_by_section
);
737 hashmap_free(network
->neighbors_by_section
);
738 hashmap_free(network
->address_labels_by_section
);
739 hashmap_free(network
->prefixes_by_section
);
740 hashmap_free(network
->route_prefixes_by_section
);
741 hashmap_free(network
->rules_by_section
);
742 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
743 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
745 if (network
->manager
&&
746 network
->manager
->duids_requesting_uuid
)
747 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
751 free(network
->dhcp_server_timezone
);
753 for (sd_dhcp_lease_server_type t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
754 free(network
->dhcp_server_emit
[t
].addresses
);
756 set_free_free(network
->dnssec_negative_trust_anchors
);
758 free(network
->lldp_mud
);
760 ordered_hashmap_free(network
->dhcp_client_send_options
);
761 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
762 ordered_hashmap_free(network
->dhcp_server_send_options
);
763 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
764 ordered_hashmap_free(network
->ipv6_tokens
);
765 ordered_hashmap_free(network
->dhcp6_client_send_options
);
766 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
768 return mfree(network
);
771 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
773 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
780 network
= ordered_hashmap_get(manager
->networks
, name
);
789 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
790 const char *ifname
, char * const *alternative_names
, const char *driver
,
791 const struct ether_addr
*mac
, const struct ether_addr
*permanent_mac
,
792 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
800 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
801 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
802 network
->match_path
, network
->match_driver
,
803 network
->match_type
, network
->match_name
, network
->match_property
,
804 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
805 device
, mac
, permanent_mac
, driver
, iftype
,
806 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
807 if (network
->match_name
&& device
) {
809 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
811 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
812 (void) safe_atou8(attr
, &name_assign_type
);
814 if (name_assign_type
== NET_NAME_ENUM
)
815 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
816 ifname
, network
->filename
);
818 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
820 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
831 int network_apply(Network
*network
, Link
*link
) {
835 link
->network
= network_ref(network
);
837 if (network
->n_dns
> 0 ||
838 !strv_isempty(network
->ntp
) ||
839 !ordered_set_isempty(network
->search_domains
) ||
840 !ordered_set_isempty(network
->route_domains
))
846 bool network_has_static_ipv6_configurations(Network
*network
) {
854 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
855 if (address
->family
== AF_INET6
)
858 LIST_FOREACH(routes
, route
, network
->static_routes
)
859 if (route
->family
== AF_INET6
)
862 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
863 if (fdb
->family
== AF_INET6
)
866 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
867 if (neighbor
->family
== AF_INET6
)
870 if (!LIST_IS_EMPTY(network
->address_labels
))
873 if (!LIST_IS_EMPTY(network
->static_prefixes
))
879 int config_parse_stacked_netdev(const char *unit
,
880 const char *filename
,
883 unsigned section_line
,
889 _cleanup_free_
char *name
= NULL
;
890 NetDevKind kind
= ltype
;
899 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
900 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
901 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
904 if (!ifname_valid(rvalue
)) {
905 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
906 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
910 name
= strdup(rvalue
);
914 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
918 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
920 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
921 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
923 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
924 "NetDev '%s' specified twice, ignoring.", name
);
931 int config_parse_domains(
933 const char *filename
,
936 unsigned section_line
,
951 if (isempty(rvalue
)) {
952 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
953 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
959 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
963 r
= extract_first_word(&p
, &w
, NULL
, 0);
965 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
966 "Failed to extract search or route domain, ignoring: %s", rvalue
);
972 is_route
= w
[0] == '~';
973 domain
= is_route
? w
+ 1 : w
;
975 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
976 /* If the root domain appears as is, or the special token "*" is found, we'll
977 * consider this as routing domain, unconditionally. */
979 domain
= "."; /* make sure we don't allow empty strings, thus write the root
982 r
= dns_name_normalize(domain
, 0, &normalized
);
984 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
985 "'%s' is not a valid domain name, ignoring.", domain
);
991 if (is_localhost(domain
)) {
992 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
993 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
999 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
1000 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
1004 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_ERR
, 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_ERR
, 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_ERR
, 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_ERR
, 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_ERR
, filename
, line
, 0,
1127 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1131 r
= dns_name_is_valid(hn
);
1133 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1134 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1138 log_syntax(unit
, LOG_ERR
, 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_ERR
)) {
1171 log_syntax(unit
, LOG_ERR
, 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
;
1199 _cleanup_free_
char *w
= NULL
;
1200 union in_addr_union a
;
1201 struct in_addr_data
*m
;
1204 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1208 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1209 "Invalid syntax, ignoring: %s", rvalue
);
1215 r
= in_addr_from_string_auto(w
, &family
, &a
);
1217 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1218 "Failed to parse dns server address, ignoring: %s", w
);
1222 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1226 m
[n
->n_dns
++] = (struct in_addr_data
) {
1237 int config_parse_dnssec_negative_trust_anchors(
1239 const char *filename
,
1241 const char *section
,
1242 unsigned section_line
,
1249 const char *p
= rvalue
;
1257 if (isempty(rvalue
)) {
1258 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1263 _cleanup_free_
char *w
= NULL
;
1265 r
= extract_first_word(&p
, &w
, NULL
, 0);
1267 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1268 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1274 r
= dns_name_is_valid(w
);
1276 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1277 "%s is not a valid domain name, ignoring.", w
);
1281 r
= set_ensure_consume(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
, TAKE_PTR(w
));
1289 int config_parse_ntp(
1291 const char *filename
,
1293 const char *section
,
1294 unsigned section_line
,
1308 if (isempty(rvalue
)) {
1314 _cleanup_free_
char *w
= NULL
;
1316 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1320 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1321 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1327 r
= dns_name_is_valid_or_address(w
);
1329 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1330 "%s is not a valid domain name or IP address, ignoring.", w
);
1334 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1335 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1336 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1337 MAX_NTP_SERVERS
, w
);
1341 r
= strv_consume(l
, TAKE_PTR(w
));
1349 int config_parse_required_for_online(
1351 const char *filename
,
1353 const char *section
,
1354 unsigned section_line
,
1361 Network
*network
= data
;
1362 LinkOperationalStateRange range
;
1363 bool required
= true;
1366 if (isempty(rvalue
)) {
1367 network
->required_for_online
= true;
1368 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1372 r
= parse_operational_state_range(rvalue
, &range
);
1374 r
= parse_boolean(rvalue
);
1376 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1377 "Failed to parse %s= setting, ignoring assignment: %s",
1383 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1386 network
->required_for_online
= required
;
1387 network
->required_operstate_for_online
= range
;
1392 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1393 "Failed to parse KeepConfiguration= setting");
1395 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1396 [KEEP_CONFIGURATION_NO
] = "no",
1397 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1398 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1399 [KEEP_CONFIGURATION_STATIC
] = "static",
1400 [KEEP_CONFIGURATION_YES
] = "yes",
1403 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1405 static const char* const ipv6_link_local_address_gen_mode_table
[_IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX
] = {
1406 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64
] = "eui64",
1407 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
] = "none",
1408 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
] = "stable-privacy",
1409 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM
] = "random",
1412 DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode
, IPv6LinkLocalAddressGenMode
);
1413 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");