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 "parse-util.h"
20 #include "path-lookup.h"
22 #include "socket-util.h"
23 #include "stat-util.h"
24 #include "string-table.h"
25 #include "string-util.h"
30 /* Let's assume that anything above this number is a user misconfiguration. */
31 #define MAX_NTP_SERVERS 128
33 /* Set defaults following RFC7844 */
34 void network_apply_anonymize_if_set(Network
*network
) {
35 if (!network
->dhcp_anonymize
)
38 SHOULD NOT send the Host Name option */
39 network
->dhcp_send_hostname
= false;
40 /* RFC7844 section 3.:
41 MAY contain the Client Identifier option
43 clients MUST use client identifiers based solely
44 on the link-layer address */
45 /* NOTE: Using MAC, as it does not reveal extra information,
46 * and some servers might not answer if this option is not sent */
47 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
49 SHOULD NOT use the Vendor Class Identifier option */
50 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
51 /* RFC7844 section 3.6.:
52 The client intending to protect its privacy SHOULD only request a
53 minimal number of options in the PRL and SHOULD also randomly shuffle
54 the ordering of option codes in the PRL. If this random ordering
55 cannot be implemented, the client MAY order the option codes in the
56 PRL by option code number (lowest to highest).
58 /* NOTE: dhcp_use_mtu is false by default,
59 * though it was not initiallized to any value in network_load_one.
60 * Maybe there should be another var called *send*?
61 * (to use the MTU sent by the server but to do not send
62 * the option in the PRL). */
63 network
->dhcp_use_mtu
= false;
64 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
65 * but this is needed to use them. */
66 network
->dhcp_use_routes
= true;
67 /* RFC7844 section 3.6.
68 * same comments as previous option */
69 network
->dhcp_use_timezone
= false;
72 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
73 const char *kind_string
;
77 /* For test-networkd-conf, the check must be earlier than the assertions. */
82 assert(network
->manager
);
83 assert(network
->filename
);
86 if (kind
== _NETDEV_KIND_TUNNEL
)
87 kind_string
= "tunnel";
89 kind_string
= netdev_kind_to_string(kind
);
91 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
92 "%s: Invalid NetDev kind of %s, ignoring assignment.",
93 network
->filename
, name
);
96 r
= netdev_get(network
->manager
, name
, &netdev
);
98 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
99 network
->filename
, name
);
101 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
108 NETDEV_KIND_IP6GRETAP
,
112 NETDEV_KIND_ERSPAN
)))
113 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
114 "%s: NetDev %s is not a %s, ignoring assignment",
115 network
->filename
, name
, kind_string
);
117 *ret_netdev
= netdev_ref(netdev
);
121 static int network_resolve_stacked_netdevs(Network
*network
) {
128 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
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
;
164 assert(network
->filename
);
166 if (set_isempty(network
->match_mac
) && set_isempty(network
->match_permanent_mac
) &&
167 strv_isempty(network
->match_path
) && strv_isempty(network
->match_driver
) &&
168 strv_isempty(network
->match_type
) && strv_isempty(network
->match_name
) &&
169 strv_isempty(network
->match_property
) && strv_isempty(network
->match_ssid
) && !network
->conditions
)
170 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
171 "%s: No valid settings found in the [Match] section, ignoring file. "
172 "To match all interfaces, add Name=* in the [Match] section.",
175 /* skip out early if configuration does not match the environment */
176 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
177 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
178 "%s: Conditions in the file do not match the system environment, skipping.",
181 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
182 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
183 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
184 (void) network_resolve_stacked_netdevs(network
);
186 /* Free unnecessary entries. */
187 network
->bond_name
= mfree(network
->bond_name
);
188 network
->bridge_name
= mfree(network
->bridge_name
);
189 network
->vrf_name
= mfree(network
->vrf_name
);
190 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
193 /* Bonding slave does not support addressing. */
194 if (network
->ipv6_accept_ra
> 0) {
195 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
197 network
->ipv6_accept_ra
= 0;
199 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
200 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
202 network
->link_local
= ADDRESS_FAMILY_NO
;
204 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
205 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
207 network
->dhcp
= ADDRESS_FAMILY_NO
;
209 if (network
->dhcp_server
) {
210 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
212 network
->dhcp_server
= false;
214 if (network
->n_static_addresses
> 0) {
215 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
217 while ((address
= network
->static_addresses
))
218 address_free(address
);
220 if (network
->n_static_routes
> 0) {
221 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
223 while ((route
= network
->static_routes
))
228 if (network
->link_local
< 0)
229 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
231 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
232 if (network
->ipv6_accept_ra
> 0) {
233 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
234 "Disabling IPv6AcceptRA=.", network
->filename
);
235 network
->ipv6_accept_ra
= false;
238 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
239 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
240 "Disabling DHCPv6 client.", network
->filename
);
241 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
244 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
245 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
246 "Disabling IPv6PrefixDelegation=.", network
->filename
);
247 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
251 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
252 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
253 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
254 "Disabling the fallback assignment.", network
->filename
);
255 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
258 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
259 network
->ipv6_accept_ra
= false;
261 /* IPMasquerade=yes implies IPForward=yes */
262 if (network
->ip_masquerade
)
263 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
265 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
266 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
267 "Disabling UseMTU=.", network
->filename
);
268 network
->dhcp_use_mtu
= false;
271 if (network
->dhcp_use_gateway
< 0)
272 network
->dhcp_use_gateway
= network
->dhcp_use_routes
;
274 if (network
->dhcp_critical
>= 0) {
275 if (network
->keep_configuration
>= 0)
276 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
277 "Ignoring CriticalConnection=.", network
->filename
);
278 else if (network
->dhcp_critical
)
279 /* CriticalConnection=yes also preserve foreign static configurations. */
280 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
282 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
285 if (network
->keep_configuration
< 0)
286 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
288 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
289 if (address_section_verify(address
) < 0)
290 address_free(address
);
292 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
293 if (route_section_verify(route
, network
) < 0)
296 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
297 if (nexthop_section_verify(nexthop
) < 0)
298 nexthop_free(nexthop
);
300 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
301 if (section_is_invalid(fdb
->section
))
304 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
305 if (neighbor_section_verify(neighbor
) < 0)
306 neighbor_free(neighbor
);
308 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
309 if (section_is_invalid(label
->section
))
310 address_label_free(label
);
312 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
313 if (section_is_invalid(prefix
->section
))
316 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
317 if (section_is_invalid(route_prefix
->section
))
318 route_prefix_free(route_prefix
);
320 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
321 if (routing_policy_rule_section_verify(rule
) < 0)
322 routing_policy_rule_free(rule
);
324 bool has_root
= false, has_clsact
= false;
325 ORDERED_HASHMAP_FOREACH(tc
, network
->tc_by_section
, i
)
326 if (traffic_control_section_verify(tc
, &has_root
, &has_clsact
) < 0)
327 traffic_control_free(tc
);
332 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
333 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
334 _cleanup_(network_unrefp
) Network
*network
= NULL
;
335 _cleanup_fclose_
FILE *file
= NULL
;
336 const char *dropin_dirname
;
343 file
= fopen(filename
, "re");
351 if (null_or_empty_fd(fileno(file
))) {
352 log_debug("Skipping empty file: %s", filename
);
356 fname
= strdup(filename
);
360 name
= strdup(basename(filename
));
364 d
= strrchr(name
, '.');
370 dropin_dirname
= strjoina(name
, ".network.d");
372 network
= new(Network
, 1);
376 *network
= (Network
) {
377 .filename
= TAKE_PTR(fname
),
378 .name
= TAKE_PTR(name
),
383 .required_for_online
= true,
384 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
385 .dhcp
= ADDRESS_FAMILY_NO
,
387 .dhcp_use_ntp
= true,
388 .dhcp_use_sip
= true,
389 .dhcp_use_dns
= true,
390 .dhcp_use_hostname
= true,
391 .dhcp_use_routes
= true,
392 .dhcp_use_gateway
= -1,
393 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
394 .dhcp_send_hostname
= true,
395 .dhcp_send_release
= true,
396 /* To enable/disable RFC7844 Anonymity Profiles */
397 .dhcp_anonymize
= false,
398 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
399 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
400 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
401 .dhcp_route_table
= RT_TABLE_MAIN
,
402 .dhcp_route_table_set
= false,
403 /* NOTE: from man: UseMTU=... Defaults to false*/
404 .dhcp_use_mtu
= false,
405 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
406 .dhcp_use_timezone
= false,
407 .rapid_commit
= true,
409 .dhcp6_use_ntp
= true,
410 .dhcp6_use_dns
= true,
412 .dhcp_server_emit_dns
= true,
413 .dhcp_server_emit_ntp
= true,
414 .dhcp_server_emit_sip
= true,
415 .dhcp_server_emit_router
= true,
416 .dhcp_server_emit_timezone
= true,
418 .router_emit_dns
= true,
419 .router_emit_domains
= true,
424 .allow_port_to_be_root
= -1,
426 .multicast_flood
= -1,
427 .multicast_to_unicast
= -1,
428 .neighbor_suppression
= -1,
430 .bridge_proxy_arp
= -1,
431 .bridge_proxy_arp_wifi
= -1,
432 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
433 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
435 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
437 .dns_default_route
= -1,
438 .llmnr
= RESOLVE_SUPPORT_YES
,
439 .mdns
= RESOLVE_SUPPORT_NO
,
440 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
441 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
443 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
444 .link_local
= _ADDRESS_FAMILY_INVALID
,
446 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
447 .ipv6_accept_ra
= -1,
448 .ipv6_dad_transmits
= -1,
449 .ipv6_hop_limit
= -1,
450 .ipv6_proxy_ndp
= -1,
451 .duid
.type
= _DUID_TYPE_INVALID
,
456 .ipv6_accept_ra_use_dns
= true,
457 .ipv6_accept_ra_use_autonomous_prefix
= true,
458 .ipv6_accept_ra_use_onlink_prefix
= true,
459 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
460 .ipv6_accept_ra_route_table_set
= false,
461 .ipv6_accept_ra_start_dhcp6_client
= true,
463 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
465 .can_triple_sampling
= -1,
466 .can_termination
= -1,
467 .ip_service_type
= -1,
470 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
477 "RoutingPolicyRule\0"
480 "DHCP\0" /* compat */
485 "IPv6NDPProxyAddress\0"
489 "IPv6PrefixDelegation\0"
493 "TrafficControlQueueingDiscipline\0"
499 "DeficitRoundRobinScheduler\0"
500 "DeficitRoundRobinSchedulerClass\0"
505 "FairQueueingControlledDelay\0"
506 "GenericRandomEarlyDetection\0"
507 "HeavyHitterFilter\0"
508 "HierarchyTokenBucket\0"
509 "HierarchyTokenBucketClass\0"
512 "StochasticFairBlue\0"
513 "StochasticFairnessQueueing\0"
514 "TokenBucketFilter\0"
515 "TrivialLinkEqualizer\0",
516 config_item_perf_lookup
, network_network_gperf_lookup
,
517 CONFIG_PARSE_WARN
, network
);
521 network_apply_anonymize_if_set(network
);
523 r
= network_add_ipv4ll_route(network
);
525 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
527 r
= network_add_default_route_on_device(network
);
529 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
533 if (stat(filename
, &stats
) < 0)
535 network
->timestamp
= timespec_load(&stats
.st_mtim
);
537 if (network_verify(network
) < 0)
538 /* Ignore .network files that do not match the conditions. */
541 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
545 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
553 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
554 _cleanup_strv_free_
char **files
= NULL
;
560 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
562 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
564 return log_error_errno(r
, "Failed to enumerate network files: %m");
566 STRV_FOREACH(f
, files
) {
567 r
= network_load_one(manager
, networks
, *f
);
569 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
575 int network_reload(Manager
*manager
) {
576 OrderedHashmap
*new_networks
= NULL
;
583 r
= network_load(manager
, &new_networks
);
587 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
588 r
= network_get_by_name(manager
, n
->name
, &old
);
590 continue; /* The .network file is new. */
592 if (n
->timestamp
!= old
->timestamp
)
593 continue; /* The .network file is modified. */
595 if (!streq(n
->filename
, old
->filename
))
598 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
606 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
607 manager
->networks
= new_networks
;
612 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
617 static Network
*network_free(Network
*network
) {
618 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
619 RoutePrefix
*route_prefix
;
620 RoutingPolicyRule
*rule
;
632 free(network
->filename
);
634 set_free_free(network
->match_mac
);
635 set_free_free(network
->match_permanent_mac
);
636 strv_free(network
->match_path
);
637 strv_free(network
->match_driver
);
638 strv_free(network
->match_type
);
639 strv_free(network
->match_name
);
640 strv_free(network
->match_property
);
641 strv_free(network
->match_wlan_iftype
);
642 strv_free(network
->match_ssid
);
643 set_free_free(network
->match_bssid
);
644 condition_free_list(network
->conditions
);
646 free(network
->description
);
647 free(network
->dhcp_vendor_class_identifier
);
648 free(network
->dhcp_mudurl
);
649 strv_free(network
->dhcp_user_class
);
650 free(network
->dhcp_hostname
);
651 set_free(network
->dhcp_black_listed_ip
);
652 set_free(network
->dhcp_request_options
);
653 set_free(network
->dhcp6_request_options
);
655 free(network
->dhcp6_mudurl
);
656 strv_free(network
->dhcp6_user_class
);
658 if (network
->dhcp_acd
)
659 sd_ipv4acd_unref(network
->dhcp_acd
);
661 strv_free(network
->ntp
);
663 strv_free(network
->sip
);
664 strv_free(network
->smtp
);
665 ordered_set_free_free(network
->search_domains
);
666 ordered_set_free_free(network
->route_domains
);
667 strv_free(network
->bind_carrier
);
669 ordered_set_free_free(network
->router_search_domains
);
670 free(network
->router_dns
);
671 set_free_free(network
->ndisc_black_listed_prefix
);
673 free(network
->bridge_name
);
674 free(network
->bond_name
);
675 free(network
->vrf_name
);
676 hashmap_free_free_key(network
->stacked_netdev_names
);
677 netdev_unref(network
->bridge
);
678 netdev_unref(network
->bond
);
679 netdev_unref(network
->vrf
);
680 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
682 while ((route
= network
->static_routes
))
685 while ((nexthop
= network
->static_nexthops
))
686 nexthop_free(nexthop
);
688 while ((address
= network
->static_addresses
))
689 address_free(address
);
691 while ((fdb_entry
= network
->static_fdb_entries
))
692 fdb_entry_free(fdb_entry
);
694 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
695 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
697 while ((neighbor
= network
->neighbors
))
698 neighbor_free(neighbor
);
700 while ((label
= network
->address_labels
))
701 address_label_free(label
);
703 while ((prefix
= network
->static_prefixes
))
706 while ((route_prefix
= network
->static_route_prefixes
))
707 route_prefix_free(route_prefix
);
709 while ((rule
= network
->rules
))
710 routing_policy_rule_free(rule
);
712 hashmap_free(network
->addresses_by_section
);
713 hashmap_free(network
->routes_by_section
);
714 hashmap_free(network
->nexthops_by_section
);
715 hashmap_free(network
->fdb_entries_by_section
);
716 hashmap_free(network
->neighbors_by_section
);
717 hashmap_free(network
->address_labels_by_section
);
718 hashmap_free(network
->prefixes_by_section
);
719 hashmap_free(network
->route_prefixes_by_section
);
720 hashmap_free(network
->rules_by_section
);
721 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
723 if (network
->manager
&&
724 network
->manager
->duids_requesting_uuid
)
725 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
729 free(network
->dhcp_server_timezone
);
730 free(network
->dhcp_server_dns
);
731 free(network
->dhcp_server_ntp
);
732 free(network
->dhcp_server_sip
);
734 set_free_free(network
->dnssec_negative_trust_anchors
);
736 free(network
->lldp_mud
);
738 ordered_hashmap_free(network
->dhcp_client_send_options
);
739 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
740 ordered_hashmap_free(network
->dhcp_server_send_options
);
741 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
742 ordered_hashmap_free(network
->ipv6_tokens
);
744 return mfree(network
);
747 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
749 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
756 network
= ordered_hashmap_get(manager
->networks
, name
);
765 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
766 const char *ifname
, char * const *alternative_names
,
767 const struct ether_addr
*address
, const struct ether_addr
*permanent_address
,
768 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
776 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
777 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
778 network
->match_path
, network
->match_driver
,
779 network
->match_type
, network
->match_name
, network
->match_property
,
780 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
781 iftype
, device
, address
, permanent_address
,
782 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
783 if (network
->match_name
&& device
) {
785 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
787 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
788 (void) safe_atou8(attr
, &name_assign_type
);
790 if (name_assign_type
== NET_NAME_ENUM
)
791 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
792 ifname
, network
->filename
);
794 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
796 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
807 int network_apply(Network
*network
, Link
*link
) {
811 link
->network
= network_ref(network
);
813 if (network
->n_dns
> 0 ||
814 !strv_isempty(network
->ntp
) ||
815 !ordered_set_isempty(network
->search_domains
) ||
816 !ordered_set_isempty(network
->route_domains
))
822 bool network_has_static_ipv6_configurations(Network
*network
) {
830 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
831 if (address
->family
== AF_INET6
)
834 LIST_FOREACH(routes
, route
, network
->static_routes
)
835 if (route
->family
== AF_INET6
)
838 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
839 if (fdb
->family
== AF_INET6
)
842 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
843 if (neighbor
->family
== AF_INET6
)
846 if (!LIST_IS_EMPTY(network
->address_labels
))
849 if (!LIST_IS_EMPTY(network
->static_prefixes
))
855 int config_parse_stacked_netdev(const char *unit
,
856 const char *filename
,
859 unsigned section_line
,
865 _cleanup_free_
char *name
= NULL
;
866 NetDevKind kind
= ltype
;
875 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
876 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
877 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
880 if (!ifname_valid(rvalue
)) {
881 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
882 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
886 name
= strdup(rvalue
);
890 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
894 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
896 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
897 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
899 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
900 "NetDev '%s' specified twice, ignoring.", name
);
907 int config_parse_domains(
909 const char *filename
,
912 unsigned section_line
,
927 if (isempty(rvalue
)) {
928 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
929 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
935 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
939 r
= extract_first_word(&p
, &w
, NULL
, 0);
941 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
942 "Failed to extract search or route domain, ignoring: %s", rvalue
);
948 is_route
= w
[0] == '~';
949 domain
= is_route
? w
+ 1 : w
;
951 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
952 /* If the root domain appears as is, or the special token "*" is found, we'll
953 * consider this as routing domain, unconditionally. */
955 domain
= "."; /* make sure we don't allow empty strings, thus write the root
958 r
= dns_name_normalize(domain
, 0, &normalized
);
960 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
961 "'%s' is not a valid domain name, ignoring.", domain
);
967 if (is_localhost(domain
)) {
968 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
969 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
975 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
976 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
980 r
= ordered_set_put_strdup(*set
, domain
);
988 int config_parse_ipv6token(
990 const char *filename
,
993 unsigned section_line
,
1000 union in_addr_union buffer
;
1001 struct in6_addr
*token
= data
;
1009 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
1011 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1012 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1016 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1017 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1018 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1022 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1023 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1024 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1028 *token
= buffer
.in6
;
1033 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1034 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1035 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1036 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1039 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1040 IPV6_PRIVACY_EXTENSIONS_YES
);
1042 int config_parse_ipv6_privacy_extensions(
1044 const char *filename
,
1046 const char *section
,
1047 unsigned section_line
,
1054 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1059 assert(ipv6_privacy_extensions
);
1061 s
= ipv6_privacy_extensions_from_string(rvalue
);
1063 if (streq(rvalue
, "kernel"))
1064 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1066 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1067 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1072 *ipv6_privacy_extensions
= s
;
1077 int config_parse_hostname(
1079 const char *filename
,
1081 const char *section
,
1082 unsigned section_line
,
1089 _cleanup_free_
char *hn
= NULL
;
1090 char **hostname
= data
;
1097 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1101 if (!hostname_is_valid(hn
, false)) {
1102 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1103 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1107 r
= dns_name_is_valid(hn
);
1109 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1110 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1114 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1115 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1119 return free_and_replace(*hostname
, hn
);
1122 int config_parse_timezone(
1124 const char *filename
,
1126 const char *section
,
1127 unsigned section_line
,
1134 _cleanup_free_
char *tz
= NULL
;
1135 char **datap
= data
;
1142 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1146 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1147 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1148 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1152 return free_and_replace(*datap
, tz
);
1155 int config_parse_dns(
1157 const char *filename
,
1159 const char *section
,
1160 unsigned section_line
,
1167 Network
*n
= userdata
;
1175 _cleanup_free_
char *w
= NULL
;
1176 union in_addr_union a
;
1177 struct in_addr_data
*m
;
1180 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1184 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1185 "Invalid syntax, ignoring: %s", rvalue
);
1191 r
= in_addr_from_string_auto(w
, &family
, &a
);
1193 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1194 "Failed to parse dns server address, ignoring: %s", w
);
1198 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1202 m
[n
->n_dns
++] = (struct in_addr_data
) {
1213 int config_parse_dnssec_negative_trust_anchors(
1215 const char *filename
,
1217 const char *section
,
1218 unsigned section_line
,
1225 const char *p
= rvalue
;
1233 if (isempty(rvalue
)) {
1234 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1239 _cleanup_free_
char *w
= NULL
;
1241 r
= extract_first_word(&p
, &w
, NULL
, 0);
1243 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1244 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1250 r
= dns_name_is_valid(w
);
1252 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1253 "%s is not a valid domain name, ignoring.", w
);
1257 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1261 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1271 int config_parse_ntp(
1273 const char *filename
,
1275 const char *section
,
1276 unsigned section_line
,
1290 if (isempty(rvalue
)) {
1296 _cleanup_free_
char *w
= NULL
;
1298 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1302 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1303 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1309 r
= dns_name_is_valid_or_address(w
);
1311 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1312 "%s is not a valid domain name or IP address, ignoring.", w
);
1316 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1317 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1318 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1319 MAX_NTP_SERVERS
, w
);
1323 r
= strv_consume(l
, TAKE_PTR(w
));
1331 int config_parse_required_for_online(
1333 const char *filename
,
1335 const char *section
,
1336 unsigned section_line
,
1343 Network
*network
= data
;
1344 LinkOperationalStateRange range
;
1345 bool required
= true;
1348 if (isempty(rvalue
)) {
1349 network
->required_for_online
= true;
1350 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1354 r
= parse_operational_state_range(rvalue
, &range
);
1356 r
= parse_boolean(rvalue
);
1358 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1359 "Failed to parse %s= setting, ignoring assignment: %s",
1365 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1368 network
->required_for_online
= required
;
1369 network
->required_operstate_for_online
= range
;
1374 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1375 "Failed to parse KeepConfiguration= setting");
1377 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1378 [KEEP_CONFIGURATION_NO
] = "no",
1379 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1380 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1381 [KEEP_CONFIGURATION_STATIC
] = "static",
1382 [KEEP_CONFIGURATION_YES
] = "yes",
1385 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);