1 /* SPDX-License-Identifier: LGPL-2.1+ */
4 #include <netinet/in.h>
5 #include <linux/netdevice.h>
7 #include "alloc-util.h"
8 #include "conf-files.h"
9 #include "conf-parser.h"
10 #include "dns-domain.h"
12 #include "hostname-util.h"
13 #include "in-addr-util.h"
14 #include "networkd-dhcp-server.h"
15 #include "network-internal.h"
16 #include "networkd-manager.h"
17 #include "networkd-network.h"
18 #include "parse-util.h"
19 #include "path-lookup.h"
21 #include "socket-util.h"
22 #include "stat-util.h"
23 #include "string-table.h"
24 #include "string-util.h"
29 /* Let's assume that anything above this number is a user misconfiguration. */
30 #define MAX_NTP_SERVERS 128
32 /* Set defaults following RFC7844 */
33 void network_apply_anonymize_if_set(Network
*network
) {
34 if (!network
->dhcp_anonymize
)
37 SHOULD NOT send the Host Name option */
38 network
->dhcp_send_hostname
= false;
39 /* RFC7844 section 3.:
40 MAY contain the Client Identifier option
42 clients MUST use client identifiers based solely
43 on the link-layer address */
44 /* NOTE: Using MAC, as it does not reveal extra information,
45 * and some servers might not answer if this option is not sent */
46 network
->dhcp_client_identifier
= DHCP_CLIENT_ID_MAC
;
48 SHOULD NOT use the Vendor Class Identifier option */
49 network
->dhcp_vendor_class_identifier
= mfree(network
->dhcp_vendor_class_identifier
);
50 /* RFC7844 section 3.6.:
51 The client intending to protect its privacy SHOULD only request a
52 minimal number of options in the PRL and SHOULD also randomly shuffle
53 the ordering of option codes in the PRL. If this random ordering
54 cannot be implemented, the client MAY order the option codes in the
55 PRL by option code number (lowest to highest).
57 /* NOTE: dhcp_use_mtu is false by default,
58 * though it was not initiallized to any value in network_load_one.
59 * Maybe there should be another var called *send*?
60 * (to use the MTU sent by the server but to do not send
61 * the option in the PRL). */
62 network
->dhcp_use_mtu
= false;
63 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
64 * but this is needed to use them. */
65 network
->dhcp_use_routes
= true;
66 /* RFC7844 section 3.6.
67 * same comments as previous option */
68 network
->dhcp_use_timezone
= false;
71 static int network_resolve_netdev_one(Network
*network
, const char *name
, NetDevKind kind
, NetDev
**ret_netdev
) {
72 const char *kind_string
;
76 /* For test-networkd-conf, the check must be earlier than the assertions. */
81 assert(network
->manager
);
82 assert(network
->filename
);
85 if (kind
== _NETDEV_KIND_TUNNEL
)
86 kind_string
= "tunnel";
88 kind_string
= netdev_kind_to_string(kind
);
90 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
91 "%s: Invalid NetDev kind of %s, ignoring assignment.",
92 network
->filename
, name
);
95 r
= netdev_get(network
->manager
, name
, &netdev
);
97 return log_error_errno(r
, "%s: %s NetDev could not be found, ignoring assignment.",
98 network
->filename
, name
);
100 if (netdev
->kind
!= kind
&& !(kind
== _NETDEV_KIND_TUNNEL
&&
107 NETDEV_KIND_IP6GRETAP
,
111 NETDEV_KIND_ERSPAN
)))
112 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
113 "%s: NetDev %s is not a %s, ignoring assignment",
114 network
->filename
, name
, kind_string
);
116 *ret_netdev
= netdev_ref(netdev
);
120 static int network_resolve_stacked_netdevs(Network
*network
) {
127 HASHMAP_FOREACH_KEY(kind
, name
, network
->stacked_netdev_names
, i
) {
128 _cleanup_(netdev_unrefp
) NetDev
*netdev
= NULL
;
130 r
= network_resolve_netdev_one(network
, name
, PTR_TO_INT(kind
), &netdev
);
134 r
= hashmap_ensure_allocated(&network
->stacked_netdevs
, &string_hash_ops
);
138 r
= hashmap_put(network
->stacked_netdevs
, netdev
->ifname
, netdev
);
140 return log_error_errno(r
, "%s: Failed to add NetDev '%s' to network: %m",
141 network
->filename
, (const char *) name
);
149 int network_verify(Network
*network
) {
150 RoutePrefix
*route_prefix
, *route_prefix_next
;
151 RoutingPolicyRule
*rule
, *rule_next
;
152 Neighbor
*neighbor
, *neighbor_next
;
153 AddressLabel
*label
, *label_next
;
154 NextHop
*nexthop
, *nextnop_next
;
155 Address
*address
, *address_next
;
156 Prefix
*prefix
, *prefix_next
;
157 Route
*route
, *route_next
;
158 FdbEntry
*fdb
, *fdb_next
;
163 assert(network
->filename
);
165 if (set_isempty(network
->match_mac
) && set_isempty(network
->match_permanent_mac
) &&
166 strv_isempty(network
->match_path
) && strv_isempty(network
->match_driver
) &&
167 strv_isempty(network
->match_type
) && strv_isempty(network
->match_name
) &&
168 strv_isempty(network
->match_property
) && strv_isempty(network
->match_ssid
) && !network
->conditions
)
169 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL
),
170 "%s: No valid settings found in the [Match] section, ignoring file. "
171 "To match all interfaces, add Name=* in the [Match] section.",
174 /* skip out early if configuration does not match the environment */
175 if (!condition_test_list(network
->conditions
, NULL
, NULL
, NULL
))
176 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
177 "%s: Conditions in the file do not match the system environment, skipping.",
180 (void) network_resolve_netdev_one(network
, network
->bond_name
, NETDEV_KIND_BOND
, &network
->bond
);
181 (void) network_resolve_netdev_one(network
, network
->bridge_name
, NETDEV_KIND_BRIDGE
, &network
->bridge
);
182 (void) network_resolve_netdev_one(network
, network
->vrf_name
, NETDEV_KIND_VRF
, &network
->vrf
);
183 (void) network_resolve_stacked_netdevs(network
);
185 /* Free unnecessary entries. */
186 network
->bond_name
= mfree(network
->bond_name
);
187 network
->bridge_name
= mfree(network
->bridge_name
);
188 network
->vrf_name
= mfree(network
->vrf_name
);
189 network
->stacked_netdev_names
= hashmap_free_free_key(network
->stacked_netdev_names
);
192 /* Bonding slave does not support addressing. */
193 if (network
->ipv6_accept_ra
> 0) {
194 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
196 network
->ipv6_accept_ra
= 0;
198 if (network
->link_local
>= 0 && network
->link_local
!= ADDRESS_FAMILY_NO
) {
199 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
201 network
->link_local
= ADDRESS_FAMILY_NO
;
203 if (network
->dhcp
!= ADDRESS_FAMILY_NO
) {
204 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
206 network
->dhcp
= ADDRESS_FAMILY_NO
;
208 if (network
->dhcp_server
) {
209 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
211 network
->dhcp_server
= false;
213 if (network
->n_static_addresses
> 0) {
214 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
216 while ((address
= network
->static_addresses
))
217 address_free(address
);
219 if (network
->n_static_routes
> 0) {
220 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
222 while ((route
= network
->static_routes
))
227 if (network
->link_local
< 0)
228 network
->link_local
= network
->bridge
? ADDRESS_FAMILY_NO
: ADDRESS_FAMILY_IPV6
;
230 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
231 if (network
->ipv6_accept_ra
> 0) {
232 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
233 "Disabling IPv6AcceptRA=.", network
->filename
);
234 network
->ipv6_accept_ra
= false;
237 if (FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV6
)) {
238 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
239 "Disabling DHCPv6 client.", network
->filename
);
240 SET_FLAG(network
->dhcp
, ADDRESS_FAMILY_IPV6
, false);
243 if (network
->router_prefix_delegation
!= RADV_PREFIX_DELEGATION_NONE
) {
244 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
245 "Disabling IPv6PrefixDelegation=.", network
->filename
);
246 network
->router_prefix_delegation
= RADV_PREFIX_DELEGATION_NONE
;
250 if (FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
) &&
251 !FLAGS_SET(network
->dhcp
, ADDRESS_FAMILY_IPV4
)) {
252 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
253 "Disabling the fallback assignment.", network
->filename
);
254 SET_FLAG(network
->link_local
, ADDRESS_FAMILY_FALLBACK_IPV4
, false);
257 if (network
->ipv6_accept_ra
< 0 && network
->bridge
)
258 network
->ipv6_accept_ra
= false;
260 /* IPMasquerade=yes implies IPForward=yes */
261 if (network
->ip_masquerade
)
262 network
->ip_forward
|= ADDRESS_FAMILY_IPV4
;
264 if (network
->mtu
> 0 && network
->dhcp_use_mtu
) {
265 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
266 "Disabling UseMTU=.", network
->filename
);
267 network
->dhcp_use_mtu
= false;
270 if (network
->dhcp_use_gateway
< 0)
271 network
->dhcp_use_gateway
= network
->dhcp_use_routes
;
273 if (network
->dhcp_critical
>= 0) {
274 if (network
->keep_configuration
>= 0)
275 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
276 "Ignoring CriticalConnection=.", network
->filename
);
277 else if (network
->dhcp_critical
)
278 /* CriticalConnection=yes also preserve foreign static configurations. */
279 network
->keep_configuration
= KEEP_CONFIGURATION_YES
;
281 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
284 if (network
->keep_configuration
< 0)
285 network
->keep_configuration
= KEEP_CONFIGURATION_NO
;
287 LIST_FOREACH_SAFE(addresses
, address
, address_next
, network
->static_addresses
)
288 if (address_section_verify(address
) < 0)
289 address_free(address
);
291 LIST_FOREACH_SAFE(routes
, route
, route_next
, network
->static_routes
)
292 if (route_section_verify(route
, network
) < 0)
295 LIST_FOREACH_SAFE(nexthops
, nexthop
, nextnop_next
, network
->static_nexthops
)
296 if (nexthop_section_verify(nexthop
) < 0)
297 nexthop_free(nexthop
);
299 LIST_FOREACH_SAFE(static_fdb_entries
, fdb
, fdb_next
, network
->static_fdb_entries
)
300 if (section_is_invalid(fdb
->section
))
303 LIST_FOREACH_SAFE(neighbors
, neighbor
, neighbor_next
, network
->neighbors
)
304 if (neighbor_section_verify(neighbor
) < 0)
305 neighbor_free(neighbor
);
307 LIST_FOREACH_SAFE(labels
, label
, label_next
, network
->address_labels
)
308 if (section_is_invalid(label
->section
))
309 address_label_free(label
);
311 LIST_FOREACH_SAFE(prefixes
, prefix
, prefix_next
, network
->static_prefixes
)
312 if (section_is_invalid(prefix
->section
))
315 LIST_FOREACH_SAFE(route_prefixes
, route_prefix
, route_prefix_next
, network
->static_route_prefixes
)
316 if (section_is_invalid(route_prefix
->section
))
317 route_prefix_free(route_prefix
);
319 LIST_FOREACH_SAFE(rules
, rule
, rule_next
, network
->rules
)
320 if (routing_policy_rule_section_verify(rule
) < 0)
321 routing_policy_rule_free(rule
);
323 bool has_root
= false, has_clsact
= false;
324 ORDERED_HASHMAP_FOREACH(tc
, network
->tc_by_section
, i
)
325 if (traffic_control_section_verify(tc
, &has_root
, &has_clsact
) < 0)
326 traffic_control_free(tc
);
331 int network_load_one(Manager
*manager
, OrderedHashmap
**networks
, const char *filename
) {
332 _cleanup_free_
char *fname
= NULL
, *name
= NULL
;
333 _cleanup_(network_unrefp
) Network
*network
= NULL
;
334 _cleanup_fclose_
FILE *file
= NULL
;
335 const char *dropin_dirname
;
342 file
= fopen(filename
, "re");
350 if (null_or_empty_fd(fileno(file
))) {
351 log_debug("Skipping empty file: %s", filename
);
355 fname
= strdup(filename
);
359 name
= strdup(basename(filename
));
363 d
= strrchr(name
, '.');
369 dropin_dirname
= strjoina(name
, ".network.d");
371 network
= new(Network
, 1);
375 *network
= (Network
) {
376 .filename
= TAKE_PTR(fname
),
377 .name
= TAKE_PTR(name
),
382 .required_for_online
= true,
383 .required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
,
384 .dhcp
= ADDRESS_FAMILY_NO
,
386 .dhcp_use_ntp
= true,
387 .dhcp_use_sip
= true,
388 .dhcp_use_dns
= true,
389 .dhcp_use_hostname
= true,
390 .dhcp_use_routes
= true,
391 .dhcp_use_gateway
= -1,
392 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
393 .dhcp_send_hostname
= true,
394 .dhcp_send_release
= true,
395 /* To enable/disable RFC7844 Anonymity Profiles */
396 .dhcp_anonymize
= false,
397 .dhcp_route_metric
= DHCP_ROUTE_METRIC
,
398 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
399 .dhcp_client_identifier
= DHCP_CLIENT_ID_DUID
,
400 .dhcp_route_table
= RT_TABLE_MAIN
,
401 .dhcp_route_table_set
= false,
402 /* NOTE: from man: UseMTU=... Defaults to false*/
403 .dhcp_use_mtu
= false,
404 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
405 .dhcp_use_timezone
= false,
406 .rapid_commit
= true,
408 .dhcp6_use_ntp
= true,
409 .dhcp6_use_dns
= true,
411 .dhcp_server_emit_dns
= true,
412 .dhcp_server_emit_ntp
= true,
413 .dhcp_server_emit_sip
= true,
414 .dhcp_server_emit_router
= true,
415 .dhcp_server_emit_timezone
= true,
417 .router_emit_dns
= true,
418 .router_emit_domains
= true,
423 .allow_port_to_be_root
= -1,
425 .multicast_flood
= -1,
426 .multicast_to_unicast
= -1,
427 .neighbor_suppression
= -1,
429 .bridge_proxy_arp
= -1,
430 .bridge_proxy_arp_wifi
= -1,
431 .priority
= LINK_BRIDGE_PORT_PRIORITY_INVALID
,
432 .multicast_router
= _MULTICAST_ROUTER_INVALID
,
434 .lldp_mode
= LLDP_MODE_ROUTERS_ONLY
,
436 .dns_default_route
= -1,
437 .llmnr
= RESOLVE_SUPPORT_YES
,
438 .mdns
= RESOLVE_SUPPORT_NO
,
439 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
440 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
442 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
443 .link_local
= _ADDRESS_FAMILY_INVALID
,
445 .ipv6_privacy_extensions
= IPV6_PRIVACY_EXTENSIONS_NO
,
446 .ipv6_accept_ra
= -1,
447 .ipv6_dad_transmits
= -1,
448 .ipv6_hop_limit
= -1,
449 .ipv6_proxy_ndp
= -1,
450 .duid
.type
= _DUID_TYPE_INVALID
,
455 .ipv6_accept_ra_use_dns
= true,
456 .ipv6_accept_ra_use_autonomous_prefix
= true,
457 .ipv6_accept_ra_use_onlink_prefix
= true,
458 .ipv6_accept_ra_route_table
= RT_TABLE_MAIN
,
459 .ipv6_accept_ra_route_table_set
= false,
460 .ipv6_accept_ra_start_dhcp6_client
= true,
462 .keep_configuration
= _KEEP_CONFIGURATION_INVALID
,
464 .can_triple_sampling
= -1,
465 .can_termination
= -1,
466 .ip_service_type
= -1,
469 r
= config_parse_many(filename
, NETWORK_DIRS
, dropin_dirname
,
476 "RoutingPolicyRule\0"
479 "DHCP\0" /* compat */
484 "IPv6NDPProxyAddress\0"
488 "IPv6PrefixDelegation\0"
492 "TrafficControlQueueingDiscipline\0"
498 "DeficitRoundRobinScheduler\0"
499 "DeficitRoundRobinSchedulerClass\0"
504 "FairQueueingControlledDelay\0"
505 "GenericRandomEarlyDetection\0"
506 "HeavyHitterFilter\0"
507 "HierarchyTokenBucket\0"
508 "HierarchyTokenBucketClass\0"
511 "StochasticFairBlue\0"
512 "StochasticFairnessQueueing\0"
513 "TokenBucketFilter\0"
514 "TrivialLinkEqualizer\0",
515 config_item_perf_lookup
, network_network_gperf_lookup
,
516 CONFIG_PARSE_WARN
, network
);
520 network_apply_anonymize_if_set(network
);
522 r
= network_add_ipv4ll_route(network
);
524 log_warning_errno(r
, "%s: Failed to add IPv4LL route, ignoring: %m", network
->filename
);
526 r
= network_add_default_route_on_device(network
);
528 log_warning_errno(r
, "%s: Failed to add default route on device, ignoring: %m",
532 if (stat(filename
, &stats
) < 0)
534 network
->timestamp
= timespec_load(&stats
.st_mtim
);
536 if (network_verify(network
) < 0)
537 /* Ignore .network files that do not match the conditions. */
540 r
= ordered_hashmap_ensure_allocated(networks
, &string_hash_ops
);
544 r
= ordered_hashmap_put(*networks
, network
->name
, network
);
552 int network_load(Manager
*manager
, OrderedHashmap
**networks
) {
553 _cleanup_strv_free_
char **files
= NULL
;
559 ordered_hashmap_clear_with_destructor(*networks
, network_unref
);
561 r
= conf_files_list_strv(&files
, ".network", NULL
, 0, NETWORK_DIRS
);
563 return log_error_errno(r
, "Failed to enumerate network files: %m");
565 STRV_FOREACH(f
, files
) {
566 r
= network_load_one(manager
, networks
, *f
);
568 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
574 int network_reload(Manager
*manager
) {
575 OrderedHashmap
*new_networks
= NULL
;
582 r
= network_load(manager
, &new_networks
);
586 ORDERED_HASHMAP_FOREACH(n
, new_networks
, i
) {
587 r
= network_get_by_name(manager
, n
->name
, &old
);
589 continue; /* The .network file is new. */
591 if (n
->timestamp
!= old
->timestamp
)
592 continue; /* The .network file is modified. */
594 if (!streq(n
->filename
, old
->filename
))
597 r
= ordered_hashmap_replace(new_networks
, old
->name
, old
);
605 ordered_hashmap_free_with_destructor(manager
->networks
, network_unref
);
606 manager
->networks
= new_networks
;
611 ordered_hashmap_free_with_destructor(new_networks
, network_unref
);
616 static Network
*network_free(Network
*network
) {
617 IPv6ProxyNDPAddress
*ipv6_proxy_ndp_address
;
618 RoutePrefix
*route_prefix
;
619 RoutingPolicyRule
*rule
;
631 free(network
->filename
);
633 set_free_free(network
->match_mac
);
634 set_free_free(network
->match_permanent_mac
);
635 strv_free(network
->match_path
);
636 strv_free(network
->match_driver
);
637 strv_free(network
->match_type
);
638 strv_free(network
->match_name
);
639 strv_free(network
->match_property
);
640 strv_free(network
->match_wlan_iftype
);
641 strv_free(network
->match_ssid
);
642 set_free_free(network
->match_bssid
);
643 condition_free_list(network
->conditions
);
645 free(network
->description
);
646 free(network
->dhcp_vendor_class_identifier
);
647 free(network
->dhcp_mudurl
);
648 strv_free(network
->dhcp_user_class
);
649 free(network
->dhcp_hostname
);
650 set_free(network
->dhcp_black_listed_ip
);
651 set_free(network
->dhcp_request_options
);
653 free(network
->dhcp6_mudurl
);
655 if (network
->dhcp_acd
)
656 sd_ipv4acd_unref(network
->dhcp_acd
);
658 strv_free(network
->ntp
);
660 strv_free(network
->sip
);
661 strv_free(network
->smtp
);
662 ordered_set_free_free(network
->search_domains
);
663 ordered_set_free_free(network
->route_domains
);
664 strv_free(network
->bind_carrier
);
666 ordered_set_free_free(network
->router_search_domains
);
667 free(network
->router_dns
);
668 set_free_free(network
->ndisc_black_listed_prefix
);
670 free(network
->bridge_name
);
671 free(network
->bond_name
);
672 free(network
->vrf_name
);
673 hashmap_free_free_key(network
->stacked_netdev_names
);
674 netdev_unref(network
->bridge
);
675 netdev_unref(network
->bond
);
676 netdev_unref(network
->vrf
);
677 hashmap_free_with_destructor(network
->stacked_netdevs
, netdev_unref
);
679 while ((route
= network
->static_routes
))
682 while ((nexthop
= network
->static_nexthops
))
683 nexthop_free(nexthop
);
685 while ((address
= network
->static_addresses
))
686 address_free(address
);
688 while ((fdb_entry
= network
->static_fdb_entries
))
689 fdb_entry_free(fdb_entry
);
691 while ((ipv6_proxy_ndp_address
= network
->ipv6_proxy_ndp_addresses
))
692 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address
);
694 while ((neighbor
= network
->neighbors
))
695 neighbor_free(neighbor
);
697 while ((label
= network
->address_labels
))
698 address_label_free(label
);
700 while ((prefix
= network
->static_prefixes
))
703 while ((route_prefix
= network
->static_route_prefixes
))
704 route_prefix_free(route_prefix
);
706 while ((rule
= network
->rules
))
707 routing_policy_rule_free(rule
);
709 hashmap_free(network
->addresses_by_section
);
710 hashmap_free(network
->routes_by_section
);
711 hashmap_free(network
->nexthops_by_section
);
712 hashmap_free(network
->fdb_entries_by_section
);
713 hashmap_free(network
->neighbors_by_section
);
714 hashmap_free(network
->address_labels_by_section
);
715 hashmap_free(network
->prefixes_by_section
);
716 hashmap_free(network
->route_prefixes_by_section
);
717 hashmap_free(network
->rules_by_section
);
718 ordered_hashmap_free_with_destructor(network
->tc_by_section
, traffic_control_free
);
720 if (network
->manager
&&
721 network
->manager
->duids_requesting_uuid
)
722 set_remove(network
->manager
->duids_requesting_uuid
, &network
->duid
);
726 free(network
->dhcp_server_timezone
);
727 free(network
->dhcp_server_dns
);
728 free(network
->dhcp_server_ntp
);
729 free(network
->dhcp_server_sip
);
731 set_free_free(network
->dnssec_negative_trust_anchors
);
733 free(network
->lldp_mud
);
735 ordered_hashmap_free(network
->dhcp_client_send_options
);
736 ordered_hashmap_free(network
->dhcp_client_send_vendor_options
);
737 ordered_hashmap_free(network
->dhcp_server_send_options
);
738 ordered_hashmap_free(network
->dhcp_server_send_vendor_options
);
739 ordered_hashmap_free(network
->ipv6_tokens
);
741 return mfree(network
);
744 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network
, network
, network_free
);
746 int network_get_by_name(Manager
*manager
, const char *name
, Network
**ret
) {
753 network
= ordered_hashmap_get(manager
->networks
, name
);
762 int network_get(Manager
*manager
, unsigned short iftype
, sd_device
*device
,
763 const char *ifname
, char * const *alternative_names
,
764 const struct ether_addr
*address
, const struct ether_addr
*permanent_address
,
765 enum nl80211_iftype wlan_iftype
, const char *ssid
, const struct ether_addr
*bssid
,
773 ORDERED_HASHMAP_FOREACH(network
, manager
->networks
, i
)
774 if (net_match_config(network
->match_mac
, network
->match_permanent_mac
,
775 network
->match_path
, network
->match_driver
,
776 network
->match_type
, network
->match_name
, network
->match_property
,
777 network
->match_wlan_iftype
, network
->match_ssid
, network
->match_bssid
,
778 iftype
, device
, address
, permanent_address
,
779 ifname
, alternative_names
, wlan_iftype
, ssid
, bssid
)) {
780 if (network
->match_name
&& device
) {
782 uint8_t name_assign_type
= NET_NAME_UNKNOWN
;
784 if (sd_device_get_sysattr_value(device
, "name_assign_type", &attr
) >= 0)
785 (void) safe_atou8(attr
, &name_assign_type
);
787 if (name_assign_type
== NET_NAME_ENUM
)
788 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
789 ifname
, network
->filename
);
791 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
793 log_debug("%s: found matching network '%s'", ifname
, network
->filename
);
804 int network_apply(Network
*network
, Link
*link
) {
808 link
->network
= network_ref(network
);
810 if (network
->n_dns
> 0 ||
811 !strv_isempty(network
->ntp
) ||
812 !ordered_set_isempty(network
->search_domains
) ||
813 !ordered_set_isempty(network
->route_domains
))
819 bool network_has_static_ipv6_configurations(Network
*network
) {
827 LIST_FOREACH(addresses
, address
, network
->static_addresses
)
828 if (address
->family
== AF_INET6
)
831 LIST_FOREACH(routes
, route
, network
->static_routes
)
832 if (route
->family
== AF_INET6
)
835 LIST_FOREACH(static_fdb_entries
, fdb
, network
->static_fdb_entries
)
836 if (fdb
->family
== AF_INET6
)
839 LIST_FOREACH(neighbors
, neighbor
, network
->neighbors
)
840 if (neighbor
->family
== AF_INET6
)
843 if (!LIST_IS_EMPTY(network
->address_labels
))
846 if (!LIST_IS_EMPTY(network
->static_prefixes
))
852 int config_parse_stacked_netdev(const char *unit
,
853 const char *filename
,
856 unsigned section_line
,
862 _cleanup_free_
char *name
= NULL
;
863 NetDevKind kind
= ltype
;
872 NETDEV_KIND_VLAN
, NETDEV_KIND_MACVLAN
, NETDEV_KIND_MACVTAP
,
873 NETDEV_KIND_IPVLAN
, NETDEV_KIND_IPVTAP
, NETDEV_KIND_VXLAN
,
874 NETDEV_KIND_L2TP
, NETDEV_KIND_MACSEC
, _NETDEV_KIND_TUNNEL
,
877 if (!ifname_valid(rvalue
)) {
878 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
879 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue
, rvalue
);
883 name
= strdup(rvalue
);
887 r
= hashmap_ensure_allocated(h
, &string_hash_ops
);
891 r
= hashmap_put(*h
, name
, INT_TO_PTR(kind
));
893 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
894 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name
);
896 log_syntax(unit
, LOG_DEBUG
, filename
, line
, r
,
897 "NetDev '%s' specified twice, ignoring.", name
);
904 int config_parse_domains(
906 const char *filename
,
909 unsigned section_line
,
924 if (isempty(rvalue
)) {
925 n
->search_domains
= ordered_set_free_free(n
->search_domains
);
926 n
->route_domains
= ordered_set_free_free(n
->route_domains
);
932 _cleanup_free_
char *w
= NULL
, *normalized
= NULL
;
936 r
= extract_first_word(&p
, &w
, NULL
, 0);
938 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
939 "Failed to extract search or route domain, ignoring: %s", rvalue
);
945 is_route
= w
[0] == '~';
946 domain
= is_route
? w
+ 1 : w
;
948 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
949 /* If the root domain appears as is, or the special token "*" is found, we'll
950 * consider this as routing domain, unconditionally. */
952 domain
= "."; /* make sure we don't allow empty strings, thus write the root
955 r
= dns_name_normalize(domain
, 0, &normalized
);
957 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
958 "'%s' is not a valid domain name, ignoring.", domain
);
964 if (is_localhost(domain
)) {
965 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
966 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
972 OrderedSet
**set
= is_route
? &n
->route_domains
: &n
->search_domains
;
973 r
= ordered_set_ensure_allocated(set
, &string_hash_ops
);
977 r
= ordered_set_put_strdup(*set
, domain
);
985 int config_parse_ipv6token(
987 const char *filename
,
990 unsigned section_line
,
997 union in_addr_union buffer
;
998 struct in6_addr
*token
= data
;
1006 r
= in_addr_from_string(AF_INET6
, rvalue
, &buffer
);
1008 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1009 "Failed to parse IPv6 token, ignoring: %s", rvalue
);
1013 if (in_addr_is_null(AF_INET6
, &buffer
)) {
1014 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1015 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue
);
1019 if ((buffer
.in6
.s6_addr32
[0] | buffer
.in6
.s6_addr32
[1]) != 0) {
1020 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1021 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue
);
1025 *token
= buffer
.in6
;
1030 static const char* const ipv6_privacy_extensions_table
[_IPV6_PRIVACY_EXTENSIONS_MAX
] = {
1031 [IPV6_PRIVACY_EXTENSIONS_NO
] = "no",
1032 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC
] = "prefer-public",
1033 [IPV6_PRIVACY_EXTENSIONS_YES
] = "yes",
1036 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions
, IPv6PrivacyExtensions
,
1037 IPV6_PRIVACY_EXTENSIONS_YES
);
1039 int config_parse_ipv6_privacy_extensions(
1041 const char *filename
,
1043 const char *section
,
1044 unsigned section_line
,
1051 IPv6PrivacyExtensions s
, *ipv6_privacy_extensions
= data
;
1056 assert(ipv6_privacy_extensions
);
1058 s
= ipv6_privacy_extensions_from_string(rvalue
);
1060 if (streq(rvalue
, "kernel"))
1061 s
= _IPV6_PRIVACY_EXTENSIONS_INVALID
;
1063 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1064 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue
);
1069 *ipv6_privacy_extensions
= s
;
1074 int config_parse_hostname(
1076 const char *filename
,
1078 const char *section
,
1079 unsigned section_line
,
1086 _cleanup_free_
char *hn
= NULL
;
1087 char **hostname
= data
;
1094 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &hn
, userdata
);
1098 if (!hostname_is_valid(hn
, false)) {
1099 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1100 "Hostname is not valid, ignoring assignment: %s", rvalue
);
1104 r
= dns_name_is_valid(hn
);
1106 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1107 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue
);
1111 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1112 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue
);
1116 return free_and_replace(*hostname
, hn
);
1119 int config_parse_timezone(
1121 const char *filename
,
1123 const char *section
,
1124 unsigned section_line
,
1131 _cleanup_free_
char *tz
= NULL
;
1132 char **datap
= data
;
1139 r
= config_parse_string(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &tz
, userdata
);
1143 if (!timezone_is_valid(tz
, LOG_ERR
)) {
1144 log_syntax(unit
, LOG_ERR
, filename
, line
, 0,
1145 "Timezone is not valid, ignoring assignment: %s", rvalue
);
1149 return free_and_replace(*datap
, tz
);
1152 int config_parse_dns(
1154 const char *filename
,
1156 const char *section
,
1157 unsigned section_line
,
1164 Network
*n
= userdata
;
1172 _cleanup_free_
char *w
= NULL
;
1173 union in_addr_union a
;
1174 struct in_addr_data
*m
;
1177 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1181 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1182 "Invalid syntax, ignoring: %s", rvalue
);
1188 r
= in_addr_from_string_auto(w
, &family
, &a
);
1190 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1191 "Failed to parse dns server address, ignoring: %s", w
);
1195 m
= reallocarray(n
->dns
, n
->n_dns
+ 1, sizeof(struct in_addr_data
));
1199 m
[n
->n_dns
++] = (struct in_addr_data
) {
1210 int config_parse_dnssec_negative_trust_anchors(
1212 const char *filename
,
1214 const char *section
,
1215 unsigned section_line
,
1222 const char *p
= rvalue
;
1230 if (isempty(rvalue
)) {
1231 n
->dnssec_negative_trust_anchors
= set_free_free(n
->dnssec_negative_trust_anchors
);
1236 _cleanup_free_
char *w
= NULL
;
1238 r
= extract_first_word(&p
, &w
, NULL
, 0);
1240 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1241 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue
);
1247 r
= dns_name_is_valid(w
);
1249 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1250 "%s is not a valid domain name, ignoring.", w
);
1254 r
= set_ensure_allocated(&n
->dnssec_negative_trust_anchors
, &dns_name_hash_ops
);
1258 r
= set_put(n
->dnssec_negative_trust_anchors
, w
);
1268 int config_parse_ntp(
1270 const char *filename
,
1272 const char *section
,
1273 unsigned section_line
,
1287 if (isempty(rvalue
)) {
1293 _cleanup_free_
char *w
= NULL
;
1295 r
= extract_first_word(&rvalue
, &w
, NULL
, 0);
1299 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1300 "Failed to extract NTP server name, ignoring: %s", rvalue
);
1306 r
= dns_name_is_valid_or_address(w
);
1308 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1309 "%s is not a valid domain name or IP address, ignoring.", w
);
1313 if (strv_length(*l
) > MAX_NTP_SERVERS
) {
1314 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1315 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1316 MAX_NTP_SERVERS
, w
);
1320 r
= strv_consume(l
, TAKE_PTR(w
));
1328 int config_parse_required_for_online(
1330 const char *filename
,
1332 const char *section
,
1333 unsigned section_line
,
1340 Network
*network
= data
;
1341 LinkOperationalStateRange range
;
1342 bool required
= true;
1345 if (isempty(rvalue
)) {
1346 network
->required_for_online
= true;
1347 network
->required_operstate_for_online
= LINK_OPERSTATE_RANGE_DEFAULT
;
1351 r
= parse_operational_state_range(rvalue
, &range
);
1353 r
= parse_boolean(rvalue
);
1355 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1356 "Failed to parse %s= setting, ignoring assignment: %s",
1362 range
= LINK_OPERSTATE_RANGE_DEFAULT
;
1365 network
->required_for_online
= required
;
1366 network
->required_operstate_for_online
= range
;
1371 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration
, keep_configuration
, KeepConfiguration
,
1372 "Failed to parse KeepConfiguration= setting");
1374 static const char* const keep_configuration_table
[_KEEP_CONFIGURATION_MAX
] = {
1375 [KEEP_CONFIGURATION_NO
] = "no",
1376 [KEEP_CONFIGURATION_DHCP_ON_STOP
] = "dhcp-on-stop",
1377 [KEEP_CONFIGURATION_DHCP
] = "dhcp",
1378 [KEEP_CONFIGURATION_STATIC
] = "static",
1379 [KEEP_CONFIGURATION_YES
] = "yes",
1382 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration
, KeepConfiguration
, KEEP_CONFIGURATION_YES
);