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_wlan_iftype
) &&
170 strv_isempty(network
->match_ssid
) && !network
->conditions
)
171 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
172 "%s: No valid settings found in the [Match] section, ignoring file. "
173 "To match all interfaces, add Name=* in the [Match] section.",
176 /* skip out early if configuration does not match the environment */
177 if (!condition_test_list(network
->conditions
, environ
, NULL
, NULL
, NULL
))
178 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
179 "%s: Conditions in the file do not match the system environment, skipping.",
182 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
183 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
184 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
185 (void) network_resolve_stacked_netdevs(network
);
187 /* Free unnecessary entries. */
188 network
->bond_name
= mfree(network
->bond_name
);
189 network
->bridge_name
= mfree(network
->bridge_name
);
190 network
->vrf_name
= mfree(network
->vrf_name
);
191 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
194 /* Bonding slave does not support addressing. */
195 if (network
->ipv6_accept_ra
> 0) {
196 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
198 network
->ipv6_accept_ra
= 0;
200 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
201 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
203 network
->link_local
= ADDRESS_FAMILY_NO
;
205 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
206 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
208 network
->dhcp
= ADDRESS_FAMILY_NO
;
210 if (network
->dhcp_server
) {
211 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
213 network
->dhcp_server
= false;
215 if (network
->n_static_addresses
> 0) {
216 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
218 while ((address
= network
->static_addresses
))
219 address_free(address
);
221 if (network
->n_static_routes
> 0) {
222 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
224 while ((route
= network
->static_routes
))
229 if (network
->link_local
< 0)
230 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
232 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
233 if (network
->ipv6_accept_ra
> 0) {
234 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
235 "Disabling IPv6AcceptRA=.", network
->filename
);
236 network
->ipv6_accept_ra
= false;
239 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
240 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
241 "Disabling DHCPv6 client.", network
->filename
);
242 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
245 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
246 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
247 "Disabling IPv6PrefixDelegation=.", network
->filename
);
248 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
252 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
253 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
254 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
255 "Disabling the fallback assignment.", network
->filename
);
256 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
259 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
260 network
->ipv6_accept_ra
= false;
262 /* IPMasquerade=yes implies IPForward=yes */
263 if (network
->ip_masquerade
)
264 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
266 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
267 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
268 "Disabling UseMTU=.", network
->filename
);
269 network
->dhcp_use_mtu
= false;
272 if (network
->dhcp_use_gateway
< 0)
273 network
->dhcp_use_gateway
= network
->dhcp_use_routes
;
275 if (network
->ignore_carrier_loss
< 0)
276 network
->ignore_carrier_loss
= network
->configure_without_carrier
;
278 if (network
->dhcp_critical
>= 0) {
279 if (network
->keep_configuration
>= 0)
280 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
281 "Ignoring CriticalConnection=.", network
->filename
);
282 else if (network
->dhcp_critical
)
283 /* CriticalConnection=yes also preserve foreign static configurations. */
284 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
286 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
289 if (network
->keep_configuration
< 0)
290 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
292 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
293 if (address_section_verify(address
) < 0)
294 address_free(address
);
296 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
297 if (route_section_verify(route
, network
) < 0)
300 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
301 if (nexthop_section_verify(nexthop
) < 0)
302 nexthop_free(nexthop
);
304 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
305 if (section_is_invalid(fdb
->section
))
308 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
309 if (neighbor_section_verify(neighbor
) < 0)
310 neighbor_free(neighbor
);
312 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
313 if (section_is_invalid(label
->section
))
314 address_label_free(label
);
316 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
317 if (section_is_invalid(prefix
->section
))
320 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
321 if (section_is_invalid(route_prefix
->section
))
322 route_prefix_free(route_prefix
);
324 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
325 if (routing_policy_rule_section_verify(rule
) < 0)
326 routing_policy_rule_free(rule
);
328 bool has_root
= false, has_clsact
= false;
329 ORDERED_HASHMAP_FOREACH(tc
, network
->tc_by_section
, i
)
330 if (traffic_control_section_verify(tc
, &has_root
, &has_clsact
) < 0)
331 traffic_control_free(tc
);
336 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
337 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
338 _cleanup_(network_unrefp
) Network
*network
= NULL
;
339 _cleanup_fclose_
FILE *file
= NULL
;
340 const char *dropin_dirname
;
347 file
= fopen(filename
, "re");
355 if (null_or_empty_fd(fileno(file
))) {
356 log_debug("Skipping empty file: %s", filename
);
360 fname
= strdup(filename
);
364 name
= strdup(basename(filename
));
368 d
= strrchr(name
, '.');
374 dropin_dirname
= strjoina(name
, ".network.d");
376 network
= new(Network
, 1);
380 *network
= (Network
) {
381 .filename
= TAKE_PTR(fname
),
382 .name
= TAKE_PTR(name
),
387 .required_for_online
= true,
388 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
389 .dhcp
= ADDRESS_FAMILY_NO
,
391 .dhcp_use_ntp
= true,
392 .dhcp_use_sip
= true,
393 .dhcp_use_dns
= true,
394 .dhcp_use_hostname
= true,
395 .dhcp_use_routes
= true,
396 .dhcp_use_gateway
= -1,
397 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
398 .dhcp_send_hostname
= true,
399 .dhcp_send_release
= true,
400 /* To enable/disable RFC7844 Anonymity Profiles */
401 .dhcp_anonymize
= false,
402 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
403 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
404 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
405 .dhcp_route_table
= RT_TABLE_MAIN
,
406 .dhcp_route_table_set
= false,
407 /* NOTE: from man: UseMTU=... Defaults to false*/
408 .dhcp_use_mtu
= false,
409 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
410 .dhcp_use_timezone
= false,
411 .rapid_commit
= true,
413 .dhcp6_route_metric
= DHCP_ROUTE_METRIC
,
414 .dhcp6_use_ntp
= true,
415 .dhcp6_use_dns
= true,
417 .dhcp6_pd_assign_prefix
= true,
419 .dhcp_server_emit_dns
= true,
420 .dhcp_server_emit_ntp
= true,
421 .dhcp_server_emit_sip
= true,
422 .dhcp_server_emit_router
= true,
423 .dhcp_server_emit_timezone
= true,
425 .router_prefix_subnet_id
= -1,
426 .router_emit_dns
= true,
427 .router_emit_domains
= true,
432 .allow_port_to_be_root
= -1,
434 .multicast_flood
= -1,
435 .multicast_to_unicast
= -1,
436 .neighbor_suppression
= -1,
438 .bridge_proxy_arp
= -1,
439 .bridge_proxy_arp_wifi
= -1,
440 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
441 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
443 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
445 .dns_default_route
= -1,
446 .llmnr
= RESOLVE_SUPPORT_YES
,
447 .mdns
= RESOLVE_SUPPORT_NO
,
448 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
449 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
451 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
452 .link_local
= _ADDRESS_FAMILY_INVALID
,
454 .ipv4_accept_local
= -1,
456 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
457 .ipv6_accept_ra
= -1,
458 .ipv6_dad_transmits
= -1,
459 .ipv6_hop_limit
= -1,
460 .ipv6_proxy_ndp
= -1,
461 .duid
.type
= _DUID_TYPE_INVALID
,
466 .ipv6_accept_ra_use_dns
= true,
467 .ipv6_accept_ra_use_autonomous_prefix
= true,
468 .ipv6_accept_ra_use_onlink_prefix
= true,
469 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
470 .ipv6_accept_ra_route_table_set
= false,
471 .ipv6_accept_ra_start_dhcp6_client
= true,
473 .configure_without_carrier
= false,
474 .ignore_carrier_loss
= -1,
475 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
476 .ipv6_address_gen_mode
= _LINK_IPV6_ADDRESS_GEN_MODE_INVALID
,
477 .can_triple_sampling
= -1,
478 .can_termination
= -1,
479 .ip_service_type
= -1,
482 r
= config_parse_many(
483 filename
, NETWORK_DIRS
, dropin_dirname
,
490 "RoutingPolicyRule\0"
493 "DHCP\0" /* compat */
498 "IPv6NDPProxyAddress\0"
502 "IPv6PrefixDelegation\0"
506 "TrafficControlQueueingDiscipline\0"
512 "DeficitRoundRobinScheduler\0"
513 "DeficitRoundRobinSchedulerClass\0"
515 "FairQueueingControlledDelay\0"
516 "GenericRandomEarlyDetection\0"
517 "HeavyHitterFilter\0"
518 "HierarchyTokenBucket\0"
519 "HierarchyTokenBucketClass\0"
525 "QuickFairQueueing\0"
526 "QuickFairQueueingClass\0"
527 "StochasticFairBlue\0"
528 "StochasticFairnessQueueing\0"
529 "TokenBucketFilter\0"
530 "TrivialLinkEqualizer\0",
531 config_item_perf_lookup
, network_network_gperf_lookup
,
534 &network
->timestamp
);
538 network_apply_anonymize_if_set(network
);
540 r
= network_add_ipv4ll_route(network
);
542 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
544 r
= network_add_default_route_on_device(network
);
546 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
549 if (network_verify(network
) < 0)
550 /* Ignore .network files that do not match the conditions. */
553 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
557 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
565 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
566 _cleanup_strv_free_
char **files
= NULL
;
572 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
574 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
576 return log_error_errno(r
, "Failed to enumerate network files: %m");
578 STRV_FOREACH(f
, files
) {
579 r
= network_load_one(manager
, networks
, *f
);
581 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
587 int network_reload(Manager
*manager
) {
588 OrderedHashmap
*new_networks
= NULL
;
595 r
= network_load(manager
, &new_networks
);
599 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
600 r
= network_get_by_name(manager
, n
->name
, &old
);
602 continue; /* The .network file is new. */
604 if (n
->timestamp
!= old
->timestamp
)
605 continue; /* The .network file is modified. */
607 if (!streq(n
->filename
, old
->filename
))
610 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
618 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
619 manager
->networks
= new_networks
;
624 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
629 static Network
*network_free(Network
*network
) {
630 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
631 RoutePrefix
*route_prefix
;
632 RoutingPolicyRule
*rule
;
644 free(network
->filename
);
646 set_free_free(network
->match_mac
);
647 set_free_free(network
->match_permanent_mac
);
648 strv_free(network
->match_path
);
649 strv_free(network
->match_driver
);
650 strv_free(network
->match_type
);
651 strv_free(network
->match_name
);
652 strv_free(network
->match_property
);
653 strv_free(network
->match_wlan_iftype
);
654 strv_free(network
->match_ssid
);
655 set_free_free(network
->match_bssid
);
656 condition_free_list(network
->conditions
);
658 free(network
->description
);
659 free(network
->dhcp_vendor_class_identifier
);
660 free(network
->dhcp_mudurl
);
661 strv_free(network
->dhcp_user_class
);
662 free(network
->dhcp_hostname
);
663 set_free(network
->dhcp_black_listed_ip
);
664 set_free(network
->dhcp_request_options
);
665 set_free(network
->dhcp6_request_options
);
667 free(network
->dhcp6_mudurl
);
668 strv_free(network
->dhcp6_user_class
);
669 strv_free(network
->dhcp6_vendor_class
);
671 if (network
->dhcp_acd
)
672 sd_ipv4acd_unref(network
->dhcp_acd
);
674 strv_free(network
->ntp
);
676 strv_free(network
->sip
);
677 strv_free(network
->smtp
);
678 ordered_set_free_free(network
->search_domains
);
679 ordered_set_free_free(network
->route_domains
);
680 strv_free(network
->bind_carrier
);
682 ordered_set_free_free(network
->router_search_domains
);
683 free(network
->router_dns
);
684 set_free_free(network
->ndisc_black_listed_prefix
);
686 free(network
->bridge_name
);
687 free(network
->bond_name
);
688 free(network
->vrf_name
);
689 hashmap_free_free_key(network
->stacked_netdev_names
);
690 netdev_unref(network
->bridge
);
691 netdev_unref(network
->bond
);
692 netdev_unref(network
->vrf
);
693 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
695 while ((route
= network
->static_routes
))
698 while ((nexthop
= network
->static_nexthops
))
699 nexthop_free(nexthop
);
701 while ((address
= network
->static_addresses
))
702 address_free(address
);
704 while ((fdb_entry
= network
->static_fdb_entries
))
705 fdb_entry_free(fdb_entry
);
707 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
708 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
710 while ((neighbor
= network
->neighbors
))
711 neighbor_free(neighbor
);
713 while ((label
= network
->address_labels
))
714 address_label_free(label
);
716 while ((prefix
= network
->static_prefixes
))
719 while ((route_prefix
= network
->static_route_prefixes
))
720 route_prefix_free(route_prefix
);
722 while ((rule
= network
->rules
))
723 routing_policy_rule_free(rule
);
725 hashmap_free(network
->addresses_by_section
);
726 hashmap_free(network
->routes_by_section
);
727 hashmap_free(network
->nexthops_by_section
);
728 hashmap_free(network
->fdb_entries_by_section
);
729 hashmap_free(network
->neighbors_by_section
);
730 hashmap_free(network
->address_labels_by_section
);
731 hashmap_free(network
->prefixes_by_section
);
732 hashmap_free(network
->route_prefixes_by_section
);
733 hashmap_free(network
->rules_by_section
);
734 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
736 if (network
->manager
&&
737 network
->manager
->duids_requesting_uuid
)
738 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
742 free(network
->dhcp_server_timezone
);
743 free(network
->dhcp_server_dns
);
744 free(network
->dhcp_server_ntp
);
745 free(network
->dhcp_server_sip
);
746 free(network
->dhcp_server_pop3
);
747 free(network
->dhcp_server_smtp
);
748 free(network
->dhcp_server_lpr
);
750 set_free_free(network
->dnssec_negative_trust_anchors
);
752 free(network
->lldp_mud
);
754 ordered_hashmap_free(network
->dhcp_client_send_options
);
755 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
756 ordered_hashmap_free(network
->dhcp_server_send_options
);
757 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
758 ordered_hashmap_free(network
->ipv6_tokens
);
759 ordered_hashmap_free(network
->dhcp6_client_send_options
);
760 ordered_hashmap_free(network
->dhcp6_client_send_vendor_options
);
762 return mfree(network
);
765 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
767 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
774 network
= ordered_hashmap_get(manager
->networks
, name
);
783 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
784 const char *ifname
, char * const *alternative_names
, const char *driver
,
785 const struct ether_addr
*mac
, const struct ether_addr
*permanent_mac
,
786 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
794 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
795 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
796 network
->match_path
, network
->match_driver
,
797 network
->match_type
, network
->match_name
, network
->match_property
,
798 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
799 device
, mac
, permanent_mac
, driver
, iftype
,
800 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
801 if (network
->match_name
&& device
) {
803 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
805 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
806 (void) safe_atou8(attr
, &name_assign_type
);
808 if (name_assign_type
== NET_NAME_ENUM
)
809 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
810 ifname
, network
->filename
);
812 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
814 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
825 int network_apply(Network
*network
, Link
*link
) {
829 link
->network
= network_ref(network
);
831 if (network
->n_dns
> 0 ||
832 !strv_isempty(network
->ntp
) ||
833 !ordered_set_isempty(network
->search_domains
) ||
834 !ordered_set_isempty(network
->route_domains
))
840 bool network_has_static_ipv6_configurations(Network
*network
) {
848 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
849 if (address
->family
== AF_INET6
)
852 LIST_FOREACH(routes
, route
, network
->static_routes
)
853 if (route
->family
== AF_INET6
)
856 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
857 if (fdb
->family
== AF_INET6
)
860 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
861 if (neighbor
->family
== AF_INET6
)
864 if (!LIST_IS_EMPTY(network
->address_labels
))
867 if (!LIST_IS_EMPTY(network
->static_prefixes
))
873 int config_parse_stacked_netdev(const char *unit
,
874 const char *filename
,
877 unsigned section_line
,
883 _cleanup_free_
char *name
= NULL
;
884 NetDevKind kind
= ltype
;
893 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
894 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
895 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
898 if (!ifname_valid(rvalue
)) {
899 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
900 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
904 name
= strdup(rvalue
);
908 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
912 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
914 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
915 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
917 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
918 "NetDev '%s' specified twice, ignoring.", name
);
925 int config_parse_domains(
927 const char *filename
,
930 unsigned section_line
,
945 if (isempty(rvalue
)) {
946 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
947 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
953 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
957 r
= extract_first_word(&p
, &w
, NULL
, 0);
959 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
960 "Failed to extract search or route domain, ignoring: %s", rvalue
);
966 is_route
= w
[0] == '~';
967 domain
= is_route
? w
+ 1 : w
;
969 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
970 /* If the root domain appears as is, or the special token "*" is found, we'll
971 * consider this as routing domain, unconditionally. */
973 domain
= "."; /* make sure we don't allow empty strings, thus write the root
976 r
= dns_name_normalize(domain
, 0, &normalized
);
978 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
979 "'%s' is not a valid domain name, ignoring.", domain
);
985 if (is_localhost(domain
)) {
986 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
987 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
993 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
994 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
998 r
= ordered_set_put_strdup(*set
, domain
);
1006 int config_parse_ipv6token(
1008 const char *filename
,
1010 const char *section
,
1011 unsigned section_line
,
1018 union in_addr_union buffer
;
1019 struct in6_addr
*token
= data
;
1027 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
1029 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1030 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1034 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1035 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1036 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1040 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1041 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1042 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1046 *token
= buffer
.in6
;
1051 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1052 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1053 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1054 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1057 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1058 IPV6_PRIVACY_EXTENSIONS_YES
);
1060 int config_parse_ipv6_privacy_extensions(
1062 const char *filename
,
1064 const char *section
,
1065 unsigned section_line
,
1072 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1077 assert(ipv6_privacy_extensions
);
1079 s
= ipv6_privacy_extensions_from_string(rvalue
);
1081 if (streq(rvalue
, "kernel"))
1082 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1084 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1085 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1090 *ipv6_privacy_extensions
= s
;
1095 int config_parse_hostname(
1097 const char *filename
,
1099 const char *section
,
1100 unsigned section_line
,
1107 _cleanup_free_
char *hn
= NULL
;
1108 char **hostname
= data
;
1115 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1119 if (!hostname_is_valid(hn
, false)) {
1120 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1121 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1125 r
= dns_name_is_valid(hn
);
1127 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1128 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1132 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1133 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1137 return free_and_replace(*hostname
, hn
);
1140 int config_parse_timezone(
1142 const char *filename
,
1144 const char *section
,
1145 unsigned section_line
,
1152 _cleanup_free_
char *tz
= NULL
;
1153 char **datap
= data
;
1160 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1164 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1165 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1166 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1170 return free_and_replace(*datap
, tz
);
1173 int config_parse_dns(
1175 const char *filename
,
1177 const char *section
,
1178 unsigned section_line
,
1185 Network
*n
= userdata
;
1193 _cleanup_free_
char *w
= NULL
;
1194 union in_addr_union a
;
1195 struct in_addr_data
*m
;
1198 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1202 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1203 "Invalid syntax, ignoring: %s", rvalue
);
1209 r
= in_addr_from_string_auto(w
, &family
, &a
);
1211 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1212 "Failed to parse dns server address, ignoring: %s", w
);
1216 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1220 m
[n
->n_dns
++] = (struct in_addr_data
) {
1231 int config_parse_dnssec_negative_trust_anchors(
1233 const char *filename
,
1235 const char *section
,
1236 unsigned section_line
,
1243 const char *p
= rvalue
;
1251 if (isempty(rvalue
)) {
1252 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1257 _cleanup_free_
char *w
= NULL
;
1259 r
= extract_first_word(&p
, &w
, NULL
, 0);
1261 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1262 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1268 r
= dns_name_is_valid(w
);
1270 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1271 "%s is not a valid domain name, ignoring.", w
);
1275 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1279 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1289 int config_parse_ntp(
1291 const char *filename
,
1293 const char *section
,
1294 unsigned section_line
,
1308 if (isempty(rvalue
)) {
1314 _cleanup_free_
char *w
= NULL
;
1316 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1320 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1321 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1327 r
= dns_name_is_valid_or_address(w
);
1329 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1330 "%s is not a valid domain name or IP address, ignoring.", w
);
1334 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1335 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1336 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1337 MAX_NTP_SERVERS
, w
);
1341 r
= strv_consume(l
, TAKE_PTR(w
));
1349 int config_parse_required_for_online(
1351 const char *filename
,
1353 const char *section
,
1354 unsigned section_line
,
1361 Network
*network
= data
;
1362 LinkOperationalStateRange range
;
1363 bool required
= true;
1366 if (isempty(rvalue
)) {
1367 network
->required_for_online
= true;
1368 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1372 r
= parse_operational_state_range(rvalue
, &range
);
1374 r
= parse_boolean(rvalue
);
1376 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1377 "Failed to parse %s= setting, ignoring assignment: %s",
1383 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1386 network
->required_for_online
= required
;
1387 network
->required_operstate_for_online
= range
;
1392 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1393 "Failed to parse KeepConfiguration= setting");
1395 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1396 [KEEP_CONFIGURATION_NO
] = "no",
1397 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1398 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1399 [KEEP_CONFIGURATION_STATIC
] = "static",
1400 [KEEP_CONFIGURATION_YES
] = "yes",
1403 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);