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
);
657 if (network
->dhcp_acd
)
658 sd_ipv4acd_unref(network
->dhcp_acd
);
660 strv_free(network
->ntp
);
662 strv_free(network
->sip
);
663 strv_free(network
->smtp
);
664 ordered_set_free_free(network
->search_domains
);
665 ordered_set_free_free(network
->route_domains
);
666 strv_free(network
->bind_carrier
);
668 ordered_set_free_free(network
->router_search_domains
);
669 free(network
->router_dns
);
670 set_free_free(network
->ndisc_black_listed_prefix
);
672 free(network
->bridge_name
);
673 free(network
->bond_name
);
674 free(network
->vrf_name
);
675 hashmap_free_free_key(network
->stacked_netdev_names
);
676 netdev_unref(network
->bridge
);
677 netdev_unref(network
->bond
);
678 netdev_unref(network
->vrf
);
679 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
681 while ((route
= network
->static_routes
))
684 while ((nexthop
= network
->static_nexthops
))
685 nexthop_free(nexthop
);
687 while ((address
= network
->static_addresses
))
688 address_free(address
);
690 while ((fdb_entry
= network
->static_fdb_entries
))
691 fdb_entry_free(fdb_entry
);
693 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
694 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
696 while ((neighbor
= network
->neighbors
))
697 neighbor_free(neighbor
);
699 while ((label
= network
->address_labels
))
700 address_label_free(label
);
702 while ((prefix
= network
->static_prefixes
))
705 while ((route_prefix
= network
->static_route_prefixes
))
706 route_prefix_free(route_prefix
);
708 while ((rule
= network
->rules
))
709 routing_policy_rule_free(rule
);
711 hashmap_free(network
->addresses_by_section
);
712 hashmap_free(network
->routes_by_section
);
713 hashmap_free(network
->nexthops_by_section
);
714 hashmap_free(network
->fdb_entries_by_section
);
715 hashmap_free(network
->neighbors_by_section
);
716 hashmap_free(network
->address_labels_by_section
);
717 hashmap_free(network
->prefixes_by_section
);
718 hashmap_free(network
->route_prefixes_by_section
);
719 hashmap_free(network
->rules_by_section
);
720 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
722 if (network
->manager
&&
723 network
->manager
->duids_requesting_uuid
)
724 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
728 free(network
->dhcp_server_timezone
);
729 free(network
->dhcp_server_dns
);
730 free(network
->dhcp_server_ntp
);
731 free(network
->dhcp_server_sip
);
733 set_free_free(network
->dnssec_negative_trust_anchors
);
735 free(network
->lldp_mud
);
737 ordered_hashmap_free(network
->dhcp_client_send_options
);
738 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
739 ordered_hashmap_free(network
->dhcp_server_send_options
);
740 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
741 ordered_hashmap_free(network
->ipv6_tokens
);
743 return mfree(network
);
746 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
748 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
755 network
= ordered_hashmap_get(manager
->networks
, name
);
764 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
765 const char *ifname
, char * const *alternative_names
,
766 const struct ether_addr
*address
, const struct ether_addr
*permanent_address
,
767 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
775 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
776 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
777 network
->match_path
, network
->match_driver
,
778 network
->match_type
, network
->match_name
, network
->match_property
,
779 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
780 iftype
, device
, address
, permanent_address
,
781 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
782 if (network
->match_name
&& device
) {
784 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
786 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
787 (void) safe_atou8(attr
, &name_assign_type
);
789 if (name_assign_type
== NET_NAME_ENUM
)
790 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
791 ifname
, network
->filename
);
793 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
795 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
806 int network_apply(Network
*network
, Link
*link
) {
810 link
->network
= network_ref(network
);
812 if (network
->n_dns
> 0 ||
813 !strv_isempty(network
->ntp
) ||
814 !ordered_set_isempty(network
->search_domains
) ||
815 !ordered_set_isempty(network
->route_domains
))
821 bool network_has_static_ipv6_configurations(Network
*network
) {
829 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
830 if (address
->family
== AF_INET6
)
833 LIST_FOREACH(routes
, route
, network
->static_routes
)
834 if (route
->family
== AF_INET6
)
837 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
838 if (fdb
->family
== AF_INET6
)
841 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
842 if (neighbor
->family
== AF_INET6
)
845 if (!LIST_IS_EMPTY(network
->address_labels
))
848 if (!LIST_IS_EMPTY(network
->static_prefixes
))
854 int config_parse_stacked_netdev(const char *unit
,
855 const char *filename
,
858 unsigned section_line
,
864 _cleanup_free_
char *name
= NULL
;
865 NetDevKind kind
= ltype
;
874 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
875 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
876 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
879 if (!ifname_valid(rvalue
)) {
880 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
881 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
885 name
= strdup(rvalue
);
889 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
893 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
895 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
896 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
898 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
899 "NetDev '%s' specified twice, ignoring.", name
);
906 int config_parse_domains(
908 const char *filename
,
911 unsigned section_line
,
926 if (isempty(rvalue
)) {
927 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
928 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
934 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
938 r
= extract_first_word(&p
, &w
, NULL
, 0);
940 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
941 "Failed to extract search or route domain, ignoring: %s", rvalue
);
947 is_route
= w
[0] == '~';
948 domain
= is_route
? w
+ 1 : w
;
950 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
951 /* If the root domain appears as is, or the special token "*" is found, we'll
952 * consider this as routing domain, unconditionally. */
954 domain
= "."; /* make sure we don't allow empty strings, thus write the root
957 r
= dns_name_normalize(domain
, 0, &normalized
);
959 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
960 "'%s' is not a valid domain name, ignoring.", domain
);
966 if (is_localhost(domain
)) {
967 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
968 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
974 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
975 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
979 r
= ordered_set_put_strdup(*set
, domain
);
987 int config_parse_ipv6token(
989 const char *filename
,
992 unsigned section_line
,
999 union in_addr_union buffer
;
1000 struct in6_addr
*token
= data
;
1008 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
1010 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1011 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1015 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1016 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1017 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1021 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1022 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1023 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1027 *token
= buffer
.in6
;
1032 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1033 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1034 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1035 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1038 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1039 IPV6_PRIVACY_EXTENSIONS_YES
);
1041 int config_parse_ipv6_privacy_extensions(
1043 const char *filename
,
1045 const char *section
,
1046 unsigned section_line
,
1053 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1058 assert(ipv6_privacy_extensions
);
1060 s
= ipv6_privacy_extensions_from_string(rvalue
);
1062 if (streq(rvalue
, "kernel"))
1063 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1065 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1066 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1071 *ipv6_privacy_extensions
= s
;
1076 int config_parse_hostname(
1078 const char *filename
,
1080 const char *section
,
1081 unsigned section_line
,
1088 _cleanup_free_
char *hn
= NULL
;
1089 char **hostname
= data
;
1096 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1100 if (!hostname_is_valid(hn
, false)) {
1101 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1102 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1106 r
= dns_name_is_valid(hn
);
1108 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1109 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1113 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1114 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1118 return free_and_replace(*hostname
, hn
);
1121 int config_parse_timezone(
1123 const char *filename
,
1125 const char *section
,
1126 unsigned section_line
,
1133 _cleanup_free_
char *tz
= NULL
;
1134 char **datap
= data
;
1141 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1145 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1146 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1147 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1151 return free_and_replace(*datap
, tz
);
1154 int config_parse_dns(
1156 const char *filename
,
1158 const char *section
,
1159 unsigned section_line
,
1166 Network
*n
= userdata
;
1174 _cleanup_free_
char *w
= NULL
;
1175 union in_addr_union a
;
1176 struct in_addr_data
*m
;
1179 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1183 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1184 "Invalid syntax, ignoring: %s", rvalue
);
1190 r
= in_addr_from_string_auto(w
, &family
, &a
);
1192 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1193 "Failed to parse dns server address, ignoring: %s", w
);
1197 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1201 m
[n
->n_dns
++] = (struct in_addr_data
) {
1212 int config_parse_dnssec_negative_trust_anchors(
1214 const char *filename
,
1216 const char *section
,
1217 unsigned section_line
,
1224 const char *p
= rvalue
;
1232 if (isempty(rvalue
)) {
1233 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1238 _cleanup_free_
char *w
= NULL
;
1240 r
= extract_first_word(&p
, &w
, NULL
, 0);
1242 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1243 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1249 r
= dns_name_is_valid(w
);
1251 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1252 "%s is not a valid domain name, ignoring.", w
);
1256 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1260 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1270 int config_parse_ntp(
1272 const char *filename
,
1274 const char *section
,
1275 unsigned section_line
,
1289 if (isempty(rvalue
)) {
1295 _cleanup_free_
char *w
= NULL
;
1297 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1301 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1302 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1308 r
= dns_name_is_valid_or_address(w
);
1310 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1311 "%s is not a valid domain name or IP address, ignoring.", w
);
1315 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1316 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1317 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1318 MAX_NTP_SERVERS
, w
);
1322 r
= strv_consume(l
, TAKE_PTR(w
));
1330 int config_parse_required_for_online(
1332 const char *filename
,
1334 const char *section
,
1335 unsigned section_line
,
1342 Network
*network
= data
;
1343 LinkOperationalStateRange range
;
1344 bool required
= true;
1347 if (isempty(rvalue
)) {
1348 network
->required_for_online
= true;
1349 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1353 r
= parse_operational_state_range(rvalue
, &range
);
1355 r
= parse_boolean(rvalue
);
1357 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1358 "Failed to parse %s= setting, ignoring assignment: %s",
1364 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1367 network
->required_for_online
= required
;
1368 network
->required_operstate_for_online
= range
;
1373 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1374 "Failed to parse KeepConfiguration= setting");
1376 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1377 [KEEP_CONFIGURATION_NO
] = "no",
1378 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1379 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1380 [KEEP_CONFIGURATION_STATIC
] = "static",
1381 [KEEP_CONFIGURATION_YES
] = "yes",
1384 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);