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-address-label.h"
18 #include "networkd-address.h"
19 #include "networkd-fdb.h"
20 #include "networkd-manager.h"
21 #include "networkd-mdb.h"
22 #include "networkd-neighbor.h"
23 #include "networkd-network.h"
24 #include "networkd-nexthop.h"
25 #include "networkd-radv.h"
26 #include "networkd-routing-policy-rule.h"
27 #include "networkd-sriov.h"
28 #include "parse-util.h"
29 #include "path-lookup.h"
31 #include "socket-util.h"
32 #include "stat-util.h"
33 #include "string-table.h"
34 #include "string-util.h"
39 /* Let's assume that anything above this number is a user misconfiguration. */
40 #define MAX_NTP_SERVERS 128
42 /* Set defaults following RFC7844 */
43 void network_apply_anonymize_if_set(Network
*network
) {
44 if (!network
->dhcp_anonymize
)
47 SHOULD NOT send the Host Name option */
48 network
->dhcp_send_hostname
= false;
49 /* RFC7844 section 3.:
50 MAY contain the Client Identifier option
52 clients MUST use client identifiers based solely
53 on the link-layer address */
54 /* NOTE: Using MAC, as it does not reveal extra information,
55 * and some servers might not answer if this option is not sent */
56 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
58 SHOULD NOT use the Vendor Class Identifier option */
59 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
60 /* RFC7844 section 3.6.:
61 The client intending to protect its privacy SHOULD only request a
62 minimal number of options in the PRL and SHOULD also randomly shuffle
63 the ordering of option codes in the PRL. If this random ordering
64 cannot be implemented, the client MAY order the option codes in the
65 PRL by option code number (lowest to highest).
67 /* NOTE: dhcp_use_mtu is false by default,
68 * though it was not initiallized to any value in network_load_one.
69 * Maybe there should be another var called *send*?
70 * (to use the MTU sent by the server but to do not send
71 * the option in the PRL). */
72 network
->dhcp_use_mtu
= false;
73 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
74 * but this is needed to use them. */
75 network
->dhcp_use_routes
= true;
76 /* RFC7844 section 3.6.
77 * same comments as previous option */
78 network
->dhcp_use_timezone
= false;
81 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
82 const char *kind_string
;
86 /* For test-networkd-conf, the check must be earlier than the assertions. */
91 assert(network
->manager
);
92 assert(network
->filename
);
95 if (kind
== _NETDEV_KIND_TUNNEL
)
96 kind_string
= "tunnel";
98 kind_string
= netdev_kind_to_string(kind
);
100 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
101 "%s: Invalid NetDev kind of %s, ignoring assignment.",
102 network
->filename
, name
);
105 r
= netdev_get(network
->manager
, name
, &netdev
);
107 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
108 network
->filename
, name
);
110 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
117 NETDEV_KIND_IP6GRETAP
,
121 NETDEV_KIND_ERSPAN
)))
122 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
123 "%s: NetDev %s is not a %s, ignoring assignment",
124 network
->filename
, name
, kind_string
);
126 *ret_netdev
= netdev_ref(netdev
);
130 static int network_resolve_stacked_netdevs(Network
*network
) {
136 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
) {
137 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
139 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
143 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
147 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
149 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
150 network
->filename
, (const char *) name
);
158 int network_verify(Network
*network
) {
160 assert(network
->filename
);
162 if (set_isempty(network
->match_mac
) && set_isempty(network
->match_permanent_mac
) &&
163 strv_isempty(network
->match_path
) && strv_isempty(network
->match_driver
) &&
164 strv_isempty(network
->match_type
) && strv_isempty(network
->match_name
) &&
165 strv_isempty(network
->match_property
) && strv_isempty(network
->match_wlan_iftype
) &&
166 strv_isempty(network
->match_ssid
) && !network
->conditions
)
167 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
168 "%s: No valid settings found in the [Match] section, ignoring file. "
169 "To match all interfaces, add Name=* in the [Match] section.",
172 /* skip out early if configuration does not match the environment */
173 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
174 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
175 "%s: Conditions in the file do not match the system environment, skipping.",
178 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
179 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
180 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
181 (void) network_resolve_stacked_netdevs(network
);
183 /* Free unnecessary entries. */
184 network
->bond_name
= mfree(network
->bond_name
);
185 network
->bridge_name
= mfree(network
->bridge_name
);
186 network
->vrf_name
= mfree(network
->vrf_name
);
187 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
190 /* Bonding slave does not support addressing. */
191 if (network
->ipv6_accept_ra
> 0) {
192 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
194 network
->ipv6_accept_ra
= 0;
196 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
197 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
199 network
->link_local
= ADDRESS_FAMILY_NO
;
201 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
202 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
204 network
->dhcp
= ADDRESS_FAMILY_NO
;
206 if (network
->dhcp_server
) {
207 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
209 network
->dhcp_server
= false;
211 if (!ordered_hashmap_isempty(network
->addresses_by_section
))
212 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
214 if (!hashmap_isempty(network
->routes_by_section
))
215 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
218 network
->addresses_by_section
= ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
219 network
->routes_by_section
= hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
222 if (network
->link_local
< 0)
223 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
225 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
226 if (network
->ipv6_accept_ra
> 0) {
227 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
228 "Disabling IPv6AcceptRA=.", network
->filename
);
229 network
->ipv6_accept_ra
= false;
232 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
233 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
234 "Disabling DHCPv6 client.", network
->filename
);
235 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
238 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
239 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
240 "Disabling IPv6PrefixDelegation=.", network
->filename
);
241 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
245 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
246 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
247 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
248 "Disabling the fallback assignment.", network
->filename
);
249 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
252 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
253 network
->ipv6_accept_ra
= false;
255 /* IPMasquerade=yes implies IPForward=yes */
256 if (network
->ip_masquerade
)
257 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
259 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
260 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
261 "Disabling UseMTU=.", network
->filename
);
262 network
->dhcp_use_mtu
= false;
265 if (network
->dhcp_use_gateway
< 0)
266 network
->dhcp_use_gateway
= network
->dhcp_use_routes
;
268 if (network
->ignore_carrier_loss
< 0)
269 network
->ignore_carrier_loss
= network
->configure_without_carrier
;
271 if (network
->dhcp_critical
>= 0) {
272 if (network
->keep_configuration
>= 0)
273 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
274 "Ignoring CriticalConnection=.", network
->filename
);
275 else if (network
->dhcp_critical
)
276 /* CriticalConnection=yes also preserve foreign static configurations. */
277 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
279 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
282 if (network
->keep_configuration
< 0)
283 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
285 if (network
->ipv6_proxy_ndp
== 0 && !set_isempty(network
->ipv6_proxy_ndp_addresses
)) {
286 log_warning("%s: IPv6ProxyNDP= is disabled. Ignoring IPv6ProxyNDPAddress=.", network
->filename
);
287 network
->ipv6_proxy_ndp_addresses
= set_free_free(network
->ipv6_proxy_ndp_addresses
);
290 network_verify_addresses(network
);
291 network_verify_routes(network
);
292 network_verify_nexthops(network
);
293 network_verify_fdb_entries(network
);
294 network_verify_mdb_entries(network
);
295 network_verify_neighbors(network
);
296 network_verify_address_labels(network
);
297 network_verify_prefixes(network
);
298 network_verify_route_prefixes(network
);
299 network_verify_routing_policy_rules(network
);
300 network_verify_traffic_control(network
);
301 network_verify_sr_iov(network
);
306 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
307 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
308 _cleanup_(network_unrefp
) Network
*network
= NULL
;
309 _cleanup_fclose_
FILE *file
= NULL
;
310 const char *dropin_dirname
;
317 file
= fopen(filename
, "re");
325 if (null_or_empty_fd(fileno(file
))) {
326 log_debug("Skipping empty file: %s", filename
);
330 fname
= strdup(filename
);
334 name
= strdup(basename(filename
));
338 d
= strrchr(name
, '.');
344 dropin_dirname
= strjoina(name
, ".network.d");
346 network
= new(Network
, 1);
350 *network
= (Network
) {
351 .filename
= TAKE_PTR(fname
),
352 .name
= TAKE_PTR(name
),
357 .required_for_online
= true,
358 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
359 .dhcp
= ADDRESS_FAMILY_NO
,
361 .dhcp_use_ntp
= true,
362 .dhcp_use_sip
= true,
363 .dhcp_use_dns
= true,
364 .dhcp_use_hostname
= true,
365 .dhcp_use_routes
= true,
366 .dhcp_use_gateway
= -1,
367 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
368 .dhcp_send_hostname
= true,
369 .dhcp_send_release
= true,
370 /* To enable/disable RFC7844 Anonymity Profiles */
371 .dhcp_anonymize
= false,
372 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
373 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
374 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
375 .dhcp_route_table
= RT_TABLE_MAIN
,
376 .dhcp_route_table_set
= false,
377 /* NOTE: from man: UseMTU=... Defaults to false*/
378 .dhcp_use_mtu
= false,
379 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
380 .dhcp_use_timezone
= false,
381 .rapid_commit
= true,
383 .dhcp6_route_metric
= DHCP_ROUTE_METRIC
,
384 .dhcp6_use_ntp
= true,
385 .dhcp6_use_dns
= true,
387 .dhcp6_pd_subnet_id
= -1,
388 .dhcp6_pd_assign
= true,
390 .dhcp_server_emit
[SD_DHCP_LEASE_DNS
].emit
= true,
391 .dhcp_server_emit
[SD_DHCP_LEASE_NTP
].emit
= true,
392 .dhcp_server_emit
[SD_DHCP_LEASE_SIP
].emit
= true,
394 .dhcp_server_emit_router
= true,
395 .dhcp_server_emit_timezone
= true,
397 .router_emit_dns
= true,
398 .router_emit_domains
= true,
403 .allow_port_to_be_root
= -1,
405 .multicast_flood
= -1,
406 .multicast_to_unicast
= -1,
407 .neighbor_suppression
= -1,
409 .bridge_proxy_arp
= -1,
410 .bridge_proxy_arp_wifi
= -1,
411 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
412 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
414 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
416 .dns_default_route
= -1,
417 .llmnr
= RESOLVE_SUPPORT_YES
,
418 .mdns
= RESOLVE_SUPPORT_NO
,
419 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
420 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
422 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
423 .link_local
= _ADDRESS_FAMILY_INVALID
,
424 .ipv6ll_address_gen_mode
= _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID
,
426 .ipv4_accept_local
= -1,
428 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
429 .ipv6_accept_ra
= -1,
430 .ipv6_dad_transmits
= -1,
431 .ipv6_hop_limit
= -1,
432 .ipv6_proxy_ndp
= -1,
433 .duid
.type
= _DUID_TYPE_INVALID
,
438 .ipv6_accept_ra_use_dns
= true,
439 .ipv6_accept_ra_use_autonomous_prefix
= true,
440 .ipv6_accept_ra_use_onlink_prefix
= true,
441 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
442 .ipv6_accept_ra_route_table_set
= false,
443 .ipv6_accept_ra_start_dhcp6_client
= true,
445 .configure_without_carrier
= false,
446 .ignore_carrier_loss
= -1,
447 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
448 .can_triple_sampling
= -1,
449 .can_termination
= -1,
450 .can_listen_only
= -1,
453 .ip_service_type
= -1,
456 r
= config_parse_many(
457 filename
, NETWORK_DIRS
, dropin_dirname
,
465 "RoutingPolicyRule\0"
468 "DHCP\0" /* compat */
471 "DHCPv6PrefixDelegation\0"
474 "IPv6NDPProxyAddress\0"
479 "IPv6PrefixDelegation\0"
483 "TrafficControlQueueingDiscipline\0"
489 "DeficitRoundRobinScheduler\0"
490 "DeficitRoundRobinSchedulerClass\0"
491 "EnhancedTransmissionSelection\0"
493 "FairQueueingControlledDelay\0"
495 "GenericRandomEarlyDetection\0"
496 "HeavyHitterFilter\0"
497 "HierarchyTokenBucket\0"
498 "HierarchyTokenBucketClass\0"
504 "QuickFairQueueing\0"
505 "QuickFairQueueingClass\0"
506 "StochasticFairBlue\0"
507 "StochasticFairnessQueueing\0"
508 "TokenBucketFilter\0"
509 "TrivialLinkEqualizer\0",
510 config_item_perf_lookup
, network_network_gperf_lookup
,
513 &network
->timestamp
);
517 network_apply_anonymize_if_set(network
);
519 r
= network_add_ipv4ll_route(network
);
521 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
523 r
= network_add_default_route_on_device(network
);
525 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
528 if (network_verify(network
) < 0)
529 /* Ignore .network files that do not match the conditions. */
532 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
536 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
544 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
545 _cleanup_strv_free_
char **files
= NULL
;
551 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
553 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
555 return log_error_errno(r
, "Failed to enumerate network files: %m");
557 STRV_FOREACH(f
, files
) {
558 r
= network_load_one(manager
, networks
, *f
);
560 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
566 int network_reload(Manager
*manager
) {
567 OrderedHashmap
*new_networks
= NULL
;
573 r
= network_load(manager
, &new_networks
);
577 ORDERED_HASHMAP_FOREACH(n
, new_networks
) {
578 r
= network_get_by_name(manager
, n
->name
, &old
);
580 continue; /* The .network file is new. */
582 if (n
->timestamp
!= old
->timestamp
)
583 continue; /* The .network file is modified. */
585 if (!streq(n
->filename
, old
->filename
))
588 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
596 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
597 manager
->networks
= new_networks
;
602 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
607 static Network
*network_free(Network
*network
) {
611 free(network
->filename
);
613 set_free_free(network
->match_mac
);
614 set_free_free(network
->match_permanent_mac
);
615 strv_free(network
->match_path
);
616 strv_free(network
->match_driver
);
617 strv_free(network
->match_type
);
618 strv_free(network
->match_name
);
619 strv_free(network
->match_property
);
620 strv_free(network
->match_wlan_iftype
);
621 strv_free(network
->match_ssid
);
622 set_free_free(network
->match_bssid
);
623 condition_free_list(network
->conditions
);
625 free(network
->description
);
626 free(network
->dhcp_vendor_class_identifier
);
627 free(network
->dhcp_mudurl
);
628 strv_free(network
->dhcp_user_class
);
629 free(network
->dhcp_hostname
);
630 set_free(network
->dhcp_deny_listed_ip
);
631 set_free(network
->dhcp_allow_listed_ip
);
632 set_free(network
->dhcp_request_options
);
633 set_free(network
->dhcp6_request_options
);
635 free(network
->dhcp6_mudurl
);
636 strv_free(network
->dhcp6_user_class
);
637 strv_free(network
->dhcp6_vendor_class
);
639 if (network
->dhcp_acd
)
640 sd_ipv4acd_unref(network
->dhcp_acd
);
642 strv_free(network
->ntp
);
643 for (unsigned i
= 0; i
< network
->n_dns
; i
++)
644 in_addr_full_free(network
->dns
[i
]);
646 ordered_set_free_free(network
->search_domains
);
647 ordered_set_free_free(network
->route_domains
);
648 strv_free(network
->bind_carrier
);
650 ordered_set_free_free(network
->router_search_domains
);
651 free(network
->router_dns
);
652 set_free_free(network
->ndisc_deny_listed_prefix
);
654 free(network
->bridge_name
);
655 free(network
->bond_name
);
656 free(network
->vrf_name
);
657 hashmap_free_free_key(network
->stacked_netdev_names
);
658 netdev_unref(network
->bridge
);
659 netdev_unref(network
->bond
);
660 netdev_unref(network
->vrf
);
661 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
663 set_free_free(network
->ipv6_proxy_ndp_addresses
);
664 ordered_hashmap_free_with_destructor(network
->addresses_by_section
, address_free
);
665 hashmap_free_with_destructor(network
->routes_by_section
, route_free
);
666 hashmap_free_with_destructor(network
->nexthops_by_section
, nexthop_free
);
667 hashmap_free_with_destructor(network
->fdb_entries_by_section
, fdb_entry_free
);
668 hashmap_free_with_destructor(network
->mdb_entries_by_section
, mdb_entry_free
);
669 hashmap_free_with_destructor(network
->neighbors_by_section
, neighbor_free
);
670 hashmap_free_with_destructor(network
->address_labels_by_section
, address_label_free
);
671 hashmap_free_with_destructor(network
->prefixes_by_section
, prefix_free
);
672 hashmap_free_with_destructor(network
->route_prefixes_by_section
, route_prefix_free
);
673 hashmap_free_with_destructor(network
->rules_by_section
, routing_policy_rule_free
);
674 ordered_hashmap_free_with_destructor(network
->sr_iov_by_section
, sr_iov_free
);
675 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
677 if (network
->manager
&&
678 network
->manager
->duids_requesting_uuid
)
679 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
683 free(network
->dhcp_server_timezone
);
685 for (sd_dhcp_lease_server_type t
= 0; t
< _SD_DHCP_LEASE_SERVER_TYPE_MAX
; t
++)
686 free(network
->dhcp_server_emit
[t
].addresses
);
688 set_free_free(network
->dnssec_negative_trust_anchors
);
690 free(network
->lldp_mud
);
692 ordered_hashmap_free(network
->dhcp_client_send_options
);
693 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
694 ordered_hashmap_free(network
->dhcp_server_send_options
);
695 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
696 ordered_set_free(network
->ipv6_tokens
);
697 ordered_hashmap_free(network
->dhcp6_client_send_options
);
698 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
700 return mfree(network
);
703 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
705 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
712 network
= ordered_hashmap_get(manager
->networks
, name
);
721 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
722 const char *ifname
, char * const *alternative_names
, const char *driver
,
723 const struct ether_addr
*mac
, const struct ether_addr
*permanent_mac
,
724 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
731 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
)
732 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
733 network
->match_path
, network
->match_driver
,
734 network
->match_type
, network
->match_name
, network
->match_property
,
735 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
736 device
, mac
, permanent_mac
, driver
, iftype
,
737 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
738 if (network
->match_name
&& device
) {
740 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
742 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
743 (void) safe_atou8(attr
, &name_assign_type
);
745 if (name_assign_type
== NET_NAME_ENUM
)
746 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
747 ifname
, network
->filename
);
749 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
751 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
762 int network_apply(Network
*network
, Link
*link
) {
766 link
->network
= network_ref(network
);
768 if (network
->n_dns
> 0 ||
769 !strv_isempty(network
->ntp
) ||
770 !ordered_set_isempty(network
->search_domains
) ||
771 !ordered_set_isempty(network
->route_domains
))
777 bool network_has_static_ipv6_configurations(Network
*network
) {
786 ORDERED_HASHMAP_FOREACH(address
, network
->addresses_by_section
)
787 if (address
->family
== AF_INET6
)
790 HASHMAP_FOREACH(route
, network
->routes_by_section
)
791 if (route
->family
== AF_INET6
)
794 HASHMAP_FOREACH(fdb
, network
->fdb_entries_by_section
)
795 if (fdb
->family
== AF_INET6
)
798 HASHMAP_FOREACH(mdb
, network
->mdb_entries_by_section
)
799 if (mdb
->family
== AF_INET6
)
802 HASHMAP_FOREACH(neighbor
, network
->neighbors_by_section
)
803 if (neighbor
->family
== AF_INET6
)
806 if (!hashmap_isempty(network
->address_labels_by_section
))
809 if (!hashmap_isempty(network
->prefixes_by_section
))
812 if (!hashmap_isempty(network
->route_prefixes_by_section
))
818 int config_parse_stacked_netdev(const char *unit
,
819 const char *filename
,
822 unsigned section_line
,
828 _cleanup_free_
char *name
= NULL
;
829 NetDevKind kind
= ltype
;
838 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
839 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
840 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
843 if (!ifname_valid(rvalue
)) {
844 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
845 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
849 name
= strdup(rvalue
);
853 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
857 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
859 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
860 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
862 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
863 "NetDev '%s' specified twice, ignoring.", name
);
870 int config_parse_domains(
872 const char *filename
,
875 unsigned section_line
,
889 if (isempty(rvalue
)) {
890 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
891 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
895 for (const char *p
= rvalue
;;) {
896 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
900 r
= extract_first_word(&p
, &w
, NULL
, 0);
904 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
905 "Failed to extract search or route domain, ignoring: %s", rvalue
);
911 is_route
= w
[0] == '~';
912 domain
= is_route
? w
+ 1 : w
;
914 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
915 /* If the root domain appears as is, or the special token "*" is found, we'll
916 * consider this as routing domain, unconditionally. */
918 domain
= "."; /* make sure we don't allow empty strings, thus write the root
921 r
= dns_name_normalize(domain
, 0, &normalized
);
923 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
924 "'%s' is not a valid domain name, ignoring.", domain
);
930 if (is_localhost(domain
)) {
931 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
932 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
938 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
939 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
943 r
= ordered_set_put_strdup(*set
, domain
);
949 int config_parse_hostname(
951 const char *filename
,
954 unsigned section_line
,
961 _cleanup_free_
char *hn
= NULL
;
962 char **hostname
= data
;
969 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
973 if (!hostname_is_valid(hn
, false)) {
974 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
975 "Hostname is not valid, ignoring assignment: %s", rvalue
);
979 r
= dns_name_is_valid(hn
);
981 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
982 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
986 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
987 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
991 return free_and_replace(*hostname
, hn
);
994 int config_parse_timezone(
996 const char *filename
,
999 unsigned section_line
,
1006 _cleanup_free_
char *tz
= NULL
;
1007 char **datap
= data
;
1014 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1018 if (!timezone_is_valid(tz
, LOG_WARNING
)) {
1019 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1020 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1024 return free_and_replace(*datap
, tz
);
1027 int config_parse_dns(
1029 const char *filename
,
1031 const char *section
,
1032 unsigned section_line
,
1039 Network
*n
= userdata
;
1046 if (isempty(rvalue
)) {
1047 for (unsigned i
= 0; i
< n
->n_dns
; i
++)
1048 in_addr_full_free(n
->dns
[i
]);
1049 n
->dns
= mfree(n
->dns
);
1054 for (const char *p
= rvalue
;;) {
1055 _cleanup_(in_addr_full_freep
) struct in_addr_full
*dns
= NULL
;
1056 _cleanup_free_
char *w
= NULL
;
1057 struct in_addr_full
**m
;
1059 r
= extract_first_word(&p
, &w
, NULL
, 0);
1063 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1064 "Invalid syntax, ignoring: %s", rvalue
);
1070 r
= in_addr_full_new_from_string(w
, &dns
);
1072 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1073 "Failed to parse dns server address, ignoring: %s", w
);
1077 if (IN_SET(dns
->port
, 53, 853))
1080 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_full
*));
1084 m
[n
->n_dns
++] = TAKE_PTR(dns
);
1089 int config_parse_dnssec_negative_trust_anchors(
1091 const char *filename
,
1093 const char *section
,
1094 unsigned section_line
,
1108 if (isempty(rvalue
)) {
1109 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1113 for (const char *p
= rvalue
;;) {
1114 _cleanup_free_
char *w
= NULL
;
1116 r
= extract_first_word(&p
, &w
, NULL
, 0);
1120 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1121 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1127 r
= dns_name_is_valid(w
);
1129 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1130 "%s is not a valid domain name, ignoring.", w
);
1134 r
= set_ensure_consume(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
, TAKE_PTR(w
));
1140 int config_parse_ntp(
1142 const char *filename
,
1144 const char *section
,
1145 unsigned section_line
,
1159 if (isempty(rvalue
)) {
1164 for (const char *p
= rvalue
;;) {
1165 _cleanup_free_
char *w
= NULL
;
1167 r
= extract_first_word(&p
, &w
, NULL
, 0);
1171 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1172 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1178 r
= dns_name_is_valid_or_address(w
);
1180 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1181 "%s is not a valid domain name or IP address, ignoring.", w
);
1185 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1186 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1187 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1188 MAX_NTP_SERVERS
, w
);
1192 r
= strv_consume(l
, TAKE_PTR(w
));
1198 int config_parse_required_for_online(
1200 const char *filename
,
1202 const char *section
,
1203 unsigned section_line
,
1210 Network
*network
= data
;
1211 LinkOperationalStateRange range
;
1212 bool required
= true;
1215 if (isempty(rvalue
)) {
1216 network
->required_for_online
= true;
1217 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1221 r
= parse_operational_state_range(rvalue
, &range
);
1223 r
= parse_boolean(rvalue
);
1225 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1226 "Failed to parse %s= setting, ignoring assignment: %s",
1232 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1235 network
->required_for_online
= required
;
1236 network
->required_operstate_for_online
= range
;
1241 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1242 "Failed to parse KeepConfiguration= setting");
1244 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1245 [KEEP_CONFIGURATION_NO
] = "no",
1246 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1247 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1248 [KEEP_CONFIGURATION_STATIC
] = "static",
1249 [KEEP_CONFIGURATION_YES
] = "yes",
1252 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);
1254 static const char* const ipv6_link_local_address_gen_mode_table
[_IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_MAX
] = {
1255 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_EUI64
] = "eui64",
1256 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE
] = "none",
1257 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY
] = "stable-privacy",
1258 [IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_RANDOM
] = "random",
1261 DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode
, IPv6LinkLocalAddressGenMode
);
1262 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");