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
) {
128 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
) {
129 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
131 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
135 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
139 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
141 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
142 network
->filename
, (const char *) name
);
150 int network_verify(Network
*network
) {
151 RoutePrefix
*route_prefix
, *route_prefix_next
;
152 RoutingPolicyRule
*rule
, *rule_next
;
153 Neighbor
*neighbor
, *neighbor_next
;
154 AddressLabel
*label
, *label_next
;
155 NextHop
*nexthop
, *nextnop_next
;
156 Address
*address
, *address_next
;
157 Prefix
*prefix
, *prefix_next
;
158 Route
*route
, *route_next
;
159 FdbEntry
*fdb
, *fdb_next
;
160 MdbEntry
*mdb
, *mdb_next
;
165 assert(network
->filename
);
167 if (set_isempty(network
->match_mac
) && set_isempty(network
->match_permanent_mac
) &&
168 strv_isempty(network
->match_path
) && strv_isempty(network
->match_driver
) &&
169 strv_isempty(network
->match_type
) && strv_isempty(network
->match_name
) &&
170 strv_isempty(network
->match_property
) && strv_isempty(network
->match_wlan_iftype
) &&
171 strv_isempty(network
->match_ssid
) && !network
->conditions
)
172 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
173 "%s: No valid settings found in the [Match] section, ignoring file. "
174 "To match all interfaces, add Name=* in the [Match] section.",
177 /* skip out early if configuration does not match the environment */
178 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
179 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
180 "%s: Conditions in the file do not match the system environment, skipping.",
183 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
184 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
185 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
186 (void) network_resolve_stacked_netdevs(network
);
188 /* Free unnecessary entries. */
189 network
->bond_name
= mfree(network
->bond_name
);
190 network
->bridge_name
= mfree(network
->bridge_name
);
191 network
->vrf_name
= mfree(network
->vrf_name
);
192 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
195 /* Bonding slave does not support addressing. */
196 if (network
->ipv6_accept_ra
> 0) {
197 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
199 network
->ipv6_accept_ra
= 0;
201 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
202 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
204 network
->link_local
= ADDRESS_FAMILY_NO
;
206 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
207 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
209 network
->dhcp
= ADDRESS_FAMILY_NO
;
211 if (network
->dhcp_server
) {
212 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
214 network
->dhcp_server
= false;
216 if (network
->n_static_addresses
> 0) {
217 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
219 while ((address
= network
->static_addresses
))
220 address_free(address
);
222 if (network
->n_static_routes
> 0) {
223 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
225 while ((route
= network
->static_routes
))
230 if (network
->link_local
< 0)
231 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
233 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
234 if (network
->ipv6_accept_ra
> 0) {
235 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
236 "Disabling IPv6AcceptRA=.", network
->filename
);
237 network
->ipv6_accept_ra
= false;
240 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
241 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
242 "Disabling DHCPv6 client.", network
->filename
);
243 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
246 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
247 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
248 "Disabling IPv6PrefixDelegation=.", network
->filename
);
249 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
253 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
254 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
255 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
256 "Disabling the fallback assignment.", network
->filename
);
257 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
260 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
261 network
->ipv6_accept_ra
= false;
263 /* IPMasquerade=yes implies IPForward=yes */
264 if (network
->ip_masquerade
)
265 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
267 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
268 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
269 "Disabling UseMTU=.", network
->filename
);
270 network
->dhcp_use_mtu
= false;
273 if (network
->dhcp_use_gateway
< 0)
274 network
->dhcp_use_gateway
= network
->dhcp_use_routes
;
276 if (network
->ignore_carrier_loss
< 0)
277 network
->ignore_carrier_loss
= network
->configure_without_carrier
;
279 if (network
->dhcp_critical
>= 0) {
280 if (network
->keep_configuration
>= 0)
281 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
282 "Ignoring CriticalConnection=.", network
->filename
);
283 else if (network
->dhcp_critical
)
284 /* CriticalConnection=yes also preserve foreign static configurations. */
285 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
287 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
290 if (network
->keep_configuration
< 0)
291 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
293 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
294 if (address_section_verify(address
) < 0)
295 address_free(address
);
297 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
298 if (route_section_verify(route
, network
) < 0)
301 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
302 if (nexthop_section_verify(nexthop
) < 0)
303 nexthop_free(nexthop
);
305 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
306 if (section_is_invalid(fdb
->section
))
309 if (!LIST_IS_EMPTY(network
->static_mdb_entries
) && !network
->bridge
) {
310 log_warning("%s: Cannot configure MDB entries on non-bridge port, ignoring [BridgeMDB] sections.",
313 while ((mdb
= network
->static_mdb_entries
))
317 LIST_FOREACH_SAFE(static_mdb_entries
, mdb
, mdb_next
, network
->static_mdb_entries
)
318 if (mdb_entry_verify(mdb
) < 0)
321 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
322 if (neighbor_section_verify(neighbor
) < 0)
323 neighbor_free(neighbor
);
325 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
326 if (section_is_invalid(label
->section
))
327 address_label_free(label
);
329 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
330 if (section_is_invalid(prefix
->section
))
333 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
334 if (section_is_invalid(route_prefix
->section
))
335 route_prefix_free(route_prefix
);
337 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
338 if (routing_policy_rule_section_verify(rule
) < 0)
339 routing_policy_rule_free(rule
);
341 bool has_root
= false, has_clsact
= false;
342 ORDERED_HASHMAP_FOREACH(tc
, network
->tc_by_section
)
343 if (traffic_control_section_verify(tc
, &has_root
, &has_clsact
) < 0)
344 traffic_control_free(tc
);
346 ORDERED_HASHMAP_FOREACH(sr_iov
, network
->sr_iov_by_section
)
347 if (sr_iov_section_verify(sr_iov
) < 0)
353 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
354 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
355 _cleanup_(network_unrefp
) Network
*network
= NULL
;
356 _cleanup_fclose_
FILE *file
= NULL
;
357 const char *dropin_dirname
;
364 file
= fopen(filename
, "re");
372 if (null_or_empty_fd(fileno(file
))) {
373 log_debug("Skipping empty file: %s", filename
);
377 fname
= strdup(filename
);
381 name
= strdup(basename(filename
));
385 d
= strrchr(name
, '.');
391 dropin_dirname
= strjoina(name
, ".network.d");
393 network
= new(Network
, 1);
397 *network
= (Network
) {
398 .filename
= TAKE_PTR(fname
),
399 .name
= TAKE_PTR(name
),
404 .required_for_online
= true,
405 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
406 .dhcp
= ADDRESS_FAMILY_NO
,
408 .dhcp_use_ntp
= true,
409 .dhcp_use_sip
= true,
410 .dhcp_use_dns
= true,
411 .dhcp_use_hostname
= true,
412 .dhcp_use_routes
= true,
413 .dhcp_use_gateway
= -1,
414 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
415 .dhcp_send_hostname
= true,
416 .dhcp_send_release
= true,
417 /* To enable/disable RFC7844 Anonymity Profiles */
418 .dhcp_anonymize
= false,
419 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
420 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
421 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
422 .dhcp_route_table
= RT_TABLE_MAIN
,
423 .dhcp_route_table_set
= false,
424 /* NOTE: from man: UseMTU=... Defaults to false*/
425 .dhcp_use_mtu
= false,
426 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
427 .dhcp_use_timezone
= false,
428 .rapid_commit
= true,
430 .dhcp6_route_metric
= DHCP_ROUTE_METRIC
,
431 .dhcp6_use_ntp
= true,
432 .dhcp6_use_dns
= true,
434 .dhcp6_pd_subnet_id
= -1,
435 .dhcp6_pd_assign
= true,
437 .dhcp_server_emit
[SD_DHCP_LEASE_DNS
].emit
= true,
438 .dhcp_server_emit
[SD_DHCP_LEASE_NTP
].emit
= true,
439 .dhcp_server_emit
[SD_DHCP_LEASE_SIP
].emit
= true,
441 .dhcp_server_emit_router
= true,
442 .dhcp_server_emit_timezone
= true,
444 .router_emit_dns
= true,
445 .router_emit_domains
= true,
450 .allow_port_to_be_root
= -1,
452 .multicast_flood
= -1,
453 .multicast_to_unicast
= -1,
454 .neighbor_suppression
= -1,
456 .bridge_proxy_arp
= -1,
457 .bridge_proxy_arp_wifi
= -1,
458 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
459 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
461 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
463 .dns_default_route
= -1,
464 .llmnr
= RESOLVE_SUPPORT_YES
,
465 .mdns
= RESOLVE_SUPPORT_NO
,
466 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
467 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
469 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
470 .link_local
= _ADDRESS_FAMILY_INVALID
,
471 .ipv6ll_address_gen_mode
= _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID
,
473 .ipv4_accept_local
= -1,
475 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
476 .ipv6_accept_ra
= -1,
477 .ipv6_dad_transmits
= -1,
478 .ipv6_hop_limit
= -1,
479 .ipv6_proxy_ndp
= -1,
480 .duid
.type
= _DUID_TYPE_INVALID
,
485 .ipv6_accept_ra_use_dns
= true,
486 .ipv6_accept_ra_use_autonomous_prefix
= true,
487 .ipv6_accept_ra_use_onlink_prefix
= true,
488 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
489 .ipv6_accept_ra_route_table_set
= false,
490 .ipv6_accept_ra_start_dhcp6_client
= true,
492 .configure_without_carrier
= false,
493 .ignore_carrier_loss
= -1,
494 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
495 .can_triple_sampling
= -1,
496 .can_termination
= -1,
497 .can_listen_only
= -1,
500 .ip_service_type
= -1,
503 r
= config_parse_many(
504 filename
, NETWORK_DIRS
, dropin_dirname
,
512 "RoutingPolicyRule\0"
515 "DHCP\0" /* compat */
518 "DHCPv6PrefixDelegation\0"
521 "IPv6NDPProxyAddress\0"
526 "IPv6PrefixDelegation\0"
530 "TrafficControlQueueingDiscipline\0"
536 "DeficitRoundRobinScheduler\0"
537 "DeficitRoundRobinSchedulerClass\0"
538 "EnhancedTransmissionSelection\0"
540 "FairQueueingControlledDelay\0"
541 "GenericRandomEarlyDetection\0"
542 "HeavyHitterFilter\0"
543 "HierarchyTokenBucket\0"
544 "HierarchyTokenBucketClass\0"
550 "QuickFairQueueing\0"
551 "QuickFairQueueingClass\0"
552 "StochasticFairBlue\0"
553 "StochasticFairnessQueueing\0"
554 "TokenBucketFilter\0"
555 "TrivialLinkEqualizer\0",
556 config_item_perf_lookup
, network_network_gperf_lookup
,
559 &network
->timestamp
);
563 network_apply_anonymize_if_set(network
);
565 r
= network_add_ipv4ll_route(network
);
567 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
569 r
= network_add_default_route_on_device(network
);
571 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
574 if (network_verify(network
) < 0)
575 /* Ignore .network files that do not match the conditions. */
578 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
582 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
590 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
591 _cleanup_strv_free_
char **files
= NULL
;
597 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
599 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
601 return log_error_errno(r
, "Failed to enumerate network files: %m");
603 STRV_FOREACH(f
, files
) {
604 r
= network_load_one(manager
, networks
, *f
);
606 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
612 int network_reload(Manager
*manager
) {
613 OrderedHashmap
*new_networks
= NULL
;
619 r
= network_load(manager
, &new_networks
);
623 ORDERED_HASHMAP_FOREACH(n
, new_networks
) {
624 r
= network_get_by_name(manager
, n
->name
, &old
);
626 continue; /* The .network file is new. */
628 if (n
->timestamp
!= old
->timestamp
)
629 continue; /* The .network file is modified. */
631 if (!streq(n
->filename
, old
->filename
))
634 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
642 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
643 manager
->networks
= new_networks
;
648 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
653 static Network
*network_free(Network
*network
) {
654 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
655 RoutePrefix
*route_prefix
;
656 RoutingPolicyRule
*rule
;
669 free(network
->filename
);
671 set_free_free(network
->match_mac
);
672 set_free_free(network
->match_permanent_mac
);
673 strv_free(network
->match_path
);
674 strv_free(network
->match_driver
);
675 strv_free(network
->match_type
);
676 strv_free(network
->match_name
);
677 strv_free(network
->match_property
);
678 strv_free(network
->match_wlan_iftype
);
679 strv_free(network
->match_ssid
);
680 set_free_free(network
->match_bssid
);
681 condition_free_list(network
->conditions
);
683 free(network
->description
);
684 free(network
->dhcp_vendor_class_identifier
);
685 free(network
->dhcp_mudurl
);
686 strv_free(network
->dhcp_user_class
);
687 free(network
->dhcp_hostname
);
688 set_free(network
->dhcp_deny_listed_ip
);
689 set_free(network
->dhcp_allow_listed_ip
);
690 set_free(network
->dhcp_request_options
);
691 set_free(network
->dhcp6_request_options
);
693 free(network
->dhcp6_mudurl
);
694 strv_free(network
->dhcp6_user_class
);
695 strv_free(network
->dhcp6_vendor_class
);
697 if (network
->dhcp_acd
)
698 sd_ipv4acd_unref(network
->dhcp_acd
);
700 strv_free(network
->ntp
);
701 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
702 in_addr_full_free(network
->dns
[i
]);
704 ordered_set_free_free(network
->search_domains
);
705 ordered_set_free_free(network
->route_domains
);
706 strv_free(network
->bind_carrier
);
708 ordered_set_free_free(network
->router_search_domains
);
709 free(network
->router_dns
);
710 set_free_free(network
->ndisc_deny_listed_prefix
);
712 free(network
->bridge_name
);
713 free(network
->bond_name
);
714 free(network
->vrf_name
);
715 hashmap_free_free_key(network
->stacked_netdev_names
);
716 netdev_unref(network
->bridge
);
717 netdev_unref(network
->bond
);
718 netdev_unref(network
->vrf
);
719 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
721 while ((route
= network
->static_routes
))
724 while ((nexthop
= network
->static_nexthops
))
725 nexthop_free(nexthop
);
727 while ((address
= network
->static_addresses
))
728 address_free(address
);
730 while ((fdb_entry
= network
->static_fdb_entries
))
731 fdb_entry_free(fdb_entry
);
733 while ((mdb_entry
= network
->static_mdb_entries
))
734 mdb_entry_free(mdb_entry
);
736 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
737 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
739 while ((neighbor
= network
->neighbors
))
740 neighbor_free(neighbor
);
742 while ((label
= network
->address_labels
))
743 address_label_free(label
);
745 while ((prefix
= network
->static_prefixes
))
748 while ((route_prefix
= network
->static_route_prefixes
))
749 route_prefix_free(route_prefix
);
751 while ((rule
= network
->rules
))
752 routing_policy_rule_free(rule
);
754 hashmap_free(network
->addresses_by_section
);
755 hashmap_free(network
->routes_by_section
);
756 hashmap_free(network
->nexthops_by_section
);
757 hashmap_free(network
->fdb_entries_by_section
);
758 hashmap_free(network
->mdb_entries_by_section
);
759 hashmap_free(network
->neighbors_by_section
);
760 hashmap_free(network
->address_labels_by_section
);
761 hashmap_free(network
->prefixes_by_section
);
762 hashmap_free(network
->route_prefixes_by_section
);
763 hashmap_free(network
->rules_by_section
);
764 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
765 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
767 if (network
->manager
&&
768 network
->manager
->duids_requesting_uuid
)
769 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
773 free(network
->dhcp_server_timezone
);
775 for (sd_dhcp_lease_server_type t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
776 free(network
->dhcp_server_emit
[t
].addresses
);
778 set_free_free(network
->dnssec_negative_trust_anchors
);
780 free(network
->lldp_mud
);
782 ordered_hashmap_free(network
->dhcp_client_send_options
);
783 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
784 ordered_hashmap_free(network
->dhcp_server_send_options
);
785 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
786 ordered_set_free(network
->ipv6_tokens
);
787 ordered_hashmap_free(network
->dhcp6_client_send_options
);
788 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
790 return mfree(network
);
793 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
795 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
802 network
= ordered_hashmap_get(manager
->networks
, name
);
811 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
812 const char *ifname
, char * const *alternative_names
, const char *driver
,
813 const struct ether_addr
*mac
, const struct ether_addr
*permanent_mac
,
814 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
821 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
)
822 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
823 network
->match_path
, network
->match_driver
,
824 network
->match_type
, network
->match_name
, network
->match_property
,
825 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
826 device
, mac
, permanent_mac
, driver
, iftype
,
827 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
828 if (network
->match_name
&& device
) {
830 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
832 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
833 (void) safe_atou8(attr
, &name_assign_type
);
835 if (name_assign_type
== NET_NAME_ENUM
)
836 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
837 ifname
, network
->filename
);
839 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
841 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
852 int network_apply(Network
*network
, Link
*link
) {
856 link
->network
= network_ref(network
);
858 if (network
->n_dns
> 0 ||
859 !strv_isempty(network
->ntp
) ||
860 !ordered_set_isempty(network
->search_domains
) ||
861 !ordered_set_isempty(network
->route_domains
))
867 bool network_has_static_ipv6_configurations(Network
*network
) {
876 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
877 if (address
->family
== AF_INET6
)
880 LIST_FOREACH(routes
, route
, network
->static_routes
)
881 if (route
->family
== AF_INET6
)
884 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
885 if (fdb
->family
== AF_INET6
)
888 LIST_FOREACH(static_mdb_entries
, mdb
, network
->static_mdb_entries
)
889 if (mdb
->family
== AF_INET6
)
892 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
893 if (neighbor
->family
== AF_INET6
)
896 if (!LIST_IS_EMPTY(network
->address_labels
))
899 if (!LIST_IS_EMPTY(network
->static_prefixes
))
905 int config_parse_stacked_netdev(const char *unit
,
906 const char *filename
,
909 unsigned section_line
,
915 _cleanup_free_
char *name
= NULL
;
916 NetDevKind kind
= ltype
;
925 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
926 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
927 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
930 if (!ifname_valid(rvalue
)) {
931 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
932 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
936 name
= strdup(rvalue
);
940 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
944 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
946 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
947 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
949 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
950 "NetDev '%s' specified twice, ignoring.", name
);
957 int config_parse_domains(
959 const char *filename
,
962 unsigned section_line
,
976 if (isempty(rvalue
)) {
977 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
978 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
982 for (const char *p
= rvalue
;;) {
983 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
987 r
= extract_first_word(&p
, &w
, NULL
, 0);
991 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
992 "Failed to extract search or route domain, ignoring: %s", rvalue
);
998 is_route
= w
[0] == '~';
999 domain
= is_route
? w
+ 1 : w
;
1001 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
1002 /* If the root domain appears as is, or the special token "*" is found, we'll
1003 * consider this as routing domain, unconditionally. */
1005 domain
= "."; /* make sure we don't allow empty strings, thus write the root
1008 r
= dns_name_normalize(domain
, 0, &normalized
);
1010 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1011 "'%s' is not a valid domain name, ignoring.", domain
);
1015 domain
= normalized
;
1017 if (is_localhost(domain
)) {
1018 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1019 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
1025 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
1026 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
1030 r
= ordered_set_put_strdup(*set
, domain
);
1036 int config_parse_ipv6token(
1038 const char *filename
,
1040 const char *section
,
1041 unsigned section_line
,
1048 union in_addr_union buffer
;
1049 struct in6_addr
*token
= data
;
1057 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
1059 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1060 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1064 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1065 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1066 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1070 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1071 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1072 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1076 *token
= buffer
.in6
;
1081 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1082 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1083 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1084 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1087 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1088 IPV6_PRIVACY_EXTENSIONS_YES
);
1090 int config_parse_ipv6_privacy_extensions(
1092 const char *filename
,
1094 const char *section
,
1095 unsigned section_line
,
1102 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1107 assert(ipv6_privacy_extensions
);
1109 s
= ipv6_privacy_extensions_from_string(rvalue
);
1111 if (streq(rvalue
, "kernel"))
1112 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1114 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1115 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1120 *ipv6_privacy_extensions
= s
;
1125 int config_parse_hostname(
1127 const char *filename
,
1129 const char *section
,
1130 unsigned section_line
,
1137 _cleanup_free_
char *hn
= NULL
;
1138 char **hostname
= data
;
1145 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1149 if (!hostname_is_valid(hn
, false)) {
1150 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1151 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1155 r
= dns_name_is_valid(hn
);
1157 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1158 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1162 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1163 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1167 return free_and_replace(*hostname
, hn
);
1170 int config_parse_timezone(
1172 const char *filename
,
1174 const char *section
,
1175 unsigned section_line
,
1182 _cleanup_free_
char *tz
= NULL
;
1183 char **datap
= data
;
1190 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1194 if (!timezone_is_valid(tz
, LOG_WARNING
)) {
1195 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1196 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1200 return free_and_replace(*datap
, tz
);
1203 int config_parse_dns(
1205 const char *filename
,
1207 const char *section
,
1208 unsigned section_line
,
1215 Network
*n
= userdata
;
1222 if (isempty(rvalue
)) {
1223 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
1224 in_addr_full_free(n
->dns
[i
]);
1225 n
->dns
= mfree(n
->dns
);
1230 for (const char *p
= rvalue
;;) {
1231 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
1232 _cleanup_free_
char *w
= NULL
;
1233 struct in_addr_full
**m
;
1235 r
= extract_first_word(&p
, &w
, NULL
, 0);
1239 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1240 "Invalid syntax, ignoring: %s", rvalue
);
1246 r
= in_addr_full_new_from_string(w
, &dns
);
1248 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1249 "Failed to parse dns server address, ignoring: %s", w
);
1253 if (IN_SET(dns
->port
, 53, 853))
1256 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
1260 m
[n
->n_dns
++] = TAKE_PTR(dns
);
1265 int config_parse_dnssec_negative_trust_anchors(
1267 const char *filename
,
1269 const char *section
,
1270 unsigned section_line
,
1284 if (isempty(rvalue
)) {
1285 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1289 for (const char *p
= rvalue
;;) {
1290 _cleanup_free_
char *w
= NULL
;
1292 r
= extract_first_word(&p
, &w
, NULL
, 0);
1296 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1297 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1303 r
= dns_name_is_valid(w
);
1305 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1306 "%s is not a valid domain name, ignoring.", w
);
1310 r
= set_ensure_consume(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
, TAKE_PTR(w
));
1316 int config_parse_ntp(
1318 const char *filename
,
1320 const char *section
,
1321 unsigned section_line
,
1335 if (isempty(rvalue
)) {
1340 for (const char *p
= rvalue
;;) {
1341 _cleanup_free_
char *w
= NULL
;
1343 r
= extract_first_word(&p
, &w
, NULL
, 0);
1347 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1348 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1354 r
= dns_name_is_valid_or_address(w
);
1356 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1357 "%s is not a valid domain name or IP address, ignoring.", w
);
1361 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1362 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1363 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1364 MAX_NTP_SERVERS
, w
);
1368 r
= strv_consume(l
, TAKE_PTR(w
));
1374 int config_parse_required_for_online(
1376 const char *filename
,
1378 const char *section
,
1379 unsigned section_line
,
1386 Network
*network
= data
;
1387 LinkOperationalStateRange range
;
1388 bool required
= true;
1391 if (isempty(rvalue
)) {
1392 network
->required_for_online
= true;
1393 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1397 r
= parse_operational_state_range(rvalue
, &range
);
1399 r
= parse_boolean(rvalue
);
1401 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1402 "Failed to parse %s= setting, ignoring assignment: %s",
1408 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1411 network
->required_for_online
= required
;
1412 network
->required_operstate_for_online
= range
;
1417 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1418 "Failed to parse KeepConfiguration= setting");
1420 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1421 [KEEP_CONFIGURATION_NO
] = "no",
1422 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1423 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1424 [KEEP_CONFIGURATION_STATIC
] = "static",
1425 [KEEP_CONFIGURATION_YES
] = "yes",
1428 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1430 static const char* const ipv6_link_local_address_gen_mode_table
[_IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX
] = {
1431 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64
] = "eui64",
1432 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
] = "none",
1433 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
] = "stable-privacy",
1434 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM
] = "random",
1437 DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode
, IPv6LinkLocalAddressGenMode
);
1438 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");