]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-network.c
Merge pull request #13500 from yuwata/udev-fix-static_node
[thirdparty/systemd.git] / src / network / networkd-network.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <net/if.h>
4 #include <netinet/in.h>
5 #include <linux/netdevice.h>
6
7 #include "alloc-util.h"
8 #include "conf-files.h"
9 #include "conf-parser.h"
10 #include "dns-domain.h"
11 #include "fd-util.h"
12 #include "hostname-util.h"
13 #include "in-addr-util.h"
14 #include "network-internal.h"
15 #include "networkd-manager.h"
16 #include "networkd-network.h"
17 #include "parse-util.h"
18 #include "set.h"
19 #include "socket-util.h"
20 #include "stat-util.h"
21 #include "string-table.h"
22 #include "string-util.h"
23 #include "strv.h"
24 #include "util.h"
25
26 /* Let's assume that anything above this number is a user misconfiguration. */
27 #define MAX_NTP_SERVERS 128
28
29 /* Set defaults following RFC7844 */
30 void network_apply_anonymize_if_set(Network *network) {
31 if (!network->dhcp_anonymize)
32 return;
33 /* RFC7844 3.7
34 SHOULD NOT send the Host Name option */
35 network->dhcp_send_hostname = false;
36 /* RFC7844 section 3.:
37 MAY contain the Client Identifier option
38 Section 3.5:
39 clients MUST use client identifiers based solely
40 on the link-layer address */
41 /* NOTE: Using MAC, as it does not reveal extra information,
42 * and some servers might not answer if this option is not sent */
43 network->dhcp_client_identifier = DHCP_CLIENT_ID_MAC;
44 /* RFC 7844 3.10:
45 SHOULD NOT use the Vendor Class Identifier option */
46 network->dhcp_vendor_class_identifier = mfree(network->dhcp_vendor_class_identifier);
47 /* RFC7844 section 3.6.:
48 The client intending to protect its privacy SHOULD only request a
49 minimal number of options in the PRL and SHOULD also randomly shuffle
50 the ordering of option codes in the PRL. If this random ordering
51 cannot be implemented, the client MAY order the option codes in the
52 PRL by option code number (lowest to highest).
53 */
54 /* NOTE: dhcp_use_mtu is false by default,
55 * though it was not initiallized to any value in network_load_one.
56 * Maybe there should be another var called *send*?
57 * (to use the MTU sent by the server but to do not send
58 * the option in the PRL). */
59 network->dhcp_use_mtu = false;
60 /* NOTE: when Anonymize=yes, the PRL route options are sent by default,
61 * but this is needed to use them. */
62 network->dhcp_use_routes = true;
63 /* RFC7844 section 3.6.
64 * same comments as previous option */
65 network->dhcp_use_timezone = false;
66 }
67
68 static int network_resolve_netdev_one(Network *network, const char *name, NetDevKind kind, NetDev **ret_netdev) {
69 const char *kind_string;
70 NetDev *netdev;
71 int r;
72
73 /* For test-networkd-conf, the check must be earlier than the assertions. */
74 if (!name)
75 return 0;
76
77 assert(network);
78 assert(network->manager);
79 assert(network->filename);
80 assert(ret_netdev);
81
82 if (kind == _NETDEV_KIND_TUNNEL)
83 kind_string = "tunnel";
84 else {
85 kind_string = netdev_kind_to_string(kind);
86 if (!kind_string)
87 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
88 "%s: Invalid NetDev kind of %s, ignoring assignment.",
89 network->filename, name);
90 }
91
92 r = netdev_get(network->manager, name, &netdev);
93 if (r < 0)
94 return log_error_errno(r, "%s: %s NetDev could not be found, ignoring assignment.",
95 network->filename, name);
96
97 if (netdev->kind != kind && !(kind == _NETDEV_KIND_TUNNEL &&
98 IN_SET(netdev->kind,
99 NETDEV_KIND_IPIP,
100 NETDEV_KIND_SIT,
101 NETDEV_KIND_GRE,
102 NETDEV_KIND_GRETAP,
103 NETDEV_KIND_IP6GRE,
104 NETDEV_KIND_IP6GRETAP,
105 NETDEV_KIND_VTI,
106 NETDEV_KIND_VTI6,
107 NETDEV_KIND_IP6TNL,
108 NETDEV_KIND_ERSPAN)))
109 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
110 "%s: NetDev %s is not a %s, ignoring assignment",
111 network->filename, name, kind_string);
112
113 *ret_netdev = netdev_ref(netdev);
114 return 1;
115 }
116
117 static int network_resolve_stacked_netdevs(Network *network) {
118 void *name, *kind;
119 Iterator i;
120 int r;
121
122 assert(network);
123
124 HASHMAP_FOREACH_KEY(kind, name, network->stacked_netdev_names, i) {
125 _cleanup_(netdev_unrefp) NetDev *netdev = NULL;
126
127 r = network_resolve_netdev_one(network, name, PTR_TO_INT(kind), &netdev);
128 if (r <= 0)
129 continue;
130
131 r = hashmap_ensure_allocated(&network->stacked_netdevs, &string_hash_ops);
132 if (r < 0)
133 return log_oom();
134
135 r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev);
136 if (r < 0)
137 return log_error_errno(r, "%s: Failed to add NetDev '%s' to network: %m",
138 network->filename, (const char *) name);
139
140 netdev = NULL;
141 }
142
143 return 0;
144 }
145
146 int network_verify(Network *network) {
147 Address *address, *address_next;
148 Route *route, *route_next;
149 FdbEntry *fdb, *fdb_next;
150 Neighbor *neighbor, *neighbor_next;
151 AddressLabel *label, *label_next;
152 Prefix *prefix, *prefix_next;
153 RoutingPolicyRule *rule, *rule_next;
154
155 assert(network);
156 assert(network->filename);
157
158 if (set_isempty(network->match_mac) && strv_isempty(network->match_path) &&
159 strv_isempty(network->match_driver) && strv_isempty(network->match_type) &&
160 strv_isempty(network->match_name) && strv_isempty(network->match_property) &&
161 !network->conditions)
162 log_warning("%s: No valid settings found in the [Match] section. "
163 "The file will match all interfaces. "
164 "If that is intended, please add Name=* in the [Match] section.",
165 network->filename);
166
167 /* skip out early if configuration does not match the environment */
168 if (!condition_test_list(network->conditions, NULL, NULL, NULL))
169 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
170 "%s: Conditions in the file do not match the system environment, skipping.",
171 network->filename);
172
173 (void) network_resolve_netdev_one(network, network->bond_name, NETDEV_KIND_BOND, &network->bond);
174 (void) network_resolve_netdev_one(network, network->bridge_name, NETDEV_KIND_BRIDGE, &network->bridge);
175 (void) network_resolve_netdev_one(network, network->vrf_name, NETDEV_KIND_VRF, &network->vrf);
176 (void) network_resolve_stacked_netdevs(network);
177
178 /* Free unnecessary entries. */
179 network->bond_name = mfree(network->bond_name);
180 network->bridge_name = mfree(network->bridge_name);
181 network->vrf_name = mfree(network->vrf_name);
182 network->stacked_netdev_names = hashmap_free_free_key(network->stacked_netdev_names);
183
184 if (network->bond) {
185 /* Bonding slave does not support addressing. */
186 if (network->ipv6_accept_ra > 0) {
187 log_warning("%s: Cannot enable IPv6AcceptRA= when Bond= is specified, disabling IPv6AcceptRA=.",
188 network->filename);
189 network->ipv6_accept_ra = 0;
190 }
191 if (network->link_local >= 0 && network->link_local != ADDRESS_FAMILY_NO) {
192 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
193 network->filename);
194 network->link_local = ADDRESS_FAMILY_NO;
195 }
196 if (network->dhcp != ADDRESS_FAMILY_NO) {
197 log_warning("%s: Cannot enable DHCP= when Bond= is specified, disabling DHCP=.",
198 network->filename);
199 network->dhcp = ADDRESS_FAMILY_NO;
200 }
201 if (network->dhcp_server) {
202 log_warning("%s: Cannot enable DHCPServer= when Bond= is specified, disabling DHCPServer=.",
203 network->filename);
204 network->dhcp_server = false;
205 }
206 if (network->n_static_addresses > 0) {
207 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
208 network->filename);
209 while ((address = network->static_addresses))
210 address_free(address);
211 }
212 if (network->n_static_routes > 0) {
213 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
214 network->filename);
215 while ((route = network->static_routes))
216 route_free(route);
217 }
218 }
219
220 if (network->link_local < 0)
221 network->link_local = network->bridge ? ADDRESS_FAMILY_NO : ADDRESS_FAMILY_IPV6;
222
223 if (!FLAGS_SET(network->link_local, ADDRESS_FAMILY_IPV6)) {
224 if (network->ipv6_accept_ra > 0) {
225 log_warning("%s: IPv6AcceptRA= is enabled by the .network file but IPv6 link local addressing is disabled. "
226 "Disabling IPv6AcceptRA=.", network->filename);
227 network->ipv6_accept_ra = false;
228 }
229
230 if (FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV6)) {
231 log_warning("%s: DHCPv6 client is enabled by the .network file but IPv6 link local addressing is disabled. "
232 "Disabling DHCPv6 client.", network->filename);
233 SET_FLAG(network->dhcp, ADDRESS_FAMILY_IPV6, false);
234 }
235
236 if (network->router_prefix_delegation != RADV_PREFIX_DELEGATION_NONE) {
237 log_warning("%s: IPv6PrefixDelegation= is enabled but IPv6 link local addressing is disabled. "
238 "Disabling IPv6PrefixDelegation=.", network->filename);
239 network->router_prefix_delegation = RADV_PREFIX_DELEGATION_NONE;
240 }
241 }
242
243 if (FLAGS_SET(network->link_local, ADDRESS_FAMILY_FALLBACK_IPV4) &&
244 !FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV4)) {
245 log_warning("%s: fallback assignment of IPv4 link local address is enabled but DHCPv4 is disabled. "
246 "Disabling the fallback assignment.", network->filename);
247 SET_FLAG(network->link_local, ADDRESS_FAMILY_FALLBACK_IPV4, false);
248 }
249
250 if (network->ipv6_accept_ra < 0 && network->bridge)
251 network->ipv6_accept_ra = false;
252
253 /* IPMasquerade=yes implies IPForward=yes */
254 if (network->ip_masquerade)
255 network->ip_forward |= ADDRESS_FAMILY_IPV4;
256
257 if (network->mtu > 0 && network->dhcp_use_mtu) {
258 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
259 "Disabling UseMTU=.", network->filename);
260 network->dhcp_use_mtu = false;
261 }
262
263 if (network->dhcp_critical >= 0) {
264 if (network->keep_configuration >= 0)
265 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
266 "Ignoring CriticalConnection=.", network->filename);
267 else if (network->dhcp_critical)
268 /* CriticalConnection=yes also preserve foreign static configurations. */
269 network->keep_configuration = KEEP_CONFIGURATION_YES;
270 else
271 /* For backward compatibility, we do not release DHCP addresses on manager stop. */
272 network->keep_configuration = KEEP_CONFIGURATION_DHCP_ON_STOP;
273 }
274
275 if (network->keep_configuration < 0)
276 /* For backward compatibility, we do not release DHCP addresses on manager stop. */
277 network->keep_configuration = KEEP_CONFIGURATION_DHCP_ON_STOP;
278
279 LIST_FOREACH_SAFE(addresses, address, address_next, network->static_addresses)
280 if (address_section_verify(address) < 0)
281 address_free(address);
282
283 LIST_FOREACH_SAFE(routes, route, route_next, network->static_routes)
284 if (route_section_verify(route, network) < 0)
285 route_free(route);
286
287 LIST_FOREACH_SAFE(static_fdb_entries, fdb, fdb_next, network->static_fdb_entries)
288 if (section_is_invalid(fdb->section))
289 fdb_entry_free(fdb);
290
291 LIST_FOREACH_SAFE(neighbors, neighbor, neighbor_next, network->neighbors)
292 if (neighbor_section_verify(neighbor) < 0)
293 neighbor_free(neighbor);
294
295 LIST_FOREACH_SAFE(labels, label, label_next, network->address_labels)
296 if (section_is_invalid(label->section))
297 address_label_free(label);
298
299 LIST_FOREACH_SAFE(prefixes, prefix, prefix_next, network->static_prefixes)
300 if (section_is_invalid(prefix->section))
301 prefix_free(prefix);
302
303 LIST_FOREACH_SAFE(rules, rule, rule_next, network->rules)
304 if (routing_policy_rule_section_verify(rule) < 0)
305 routing_policy_rule_free(rule);
306
307 return 0;
308 }
309
310 int network_load_one(Manager *manager, const char *filename) {
311 _cleanup_free_ char *fname = NULL, *name = NULL;
312 _cleanup_(network_unrefp) Network *network = NULL;
313 _cleanup_fclose_ FILE *file = NULL;
314 const char *dropin_dirname;
315 char *d;
316 int r;
317
318 assert(manager);
319 assert(filename);
320
321 file = fopen(filename, "re");
322 if (!file) {
323 if (errno == ENOENT)
324 return 0;
325
326 return -errno;
327 }
328
329 if (null_or_empty_fd(fileno(file))) {
330 log_debug("Skipping empty file: %s", filename);
331 return 0;
332 }
333
334 fname = strdup(filename);
335 if (!fname)
336 return log_oom();
337
338 name = strdup(basename(filename));
339 if (!name)
340 return log_oom();
341
342 d = strrchr(name, '.');
343 if (!d)
344 return -EINVAL;
345
346 *d = '\0';
347
348 dropin_dirname = strjoina(name, ".network.d");
349
350 network = new(Network, 1);
351 if (!network)
352 return log_oom();
353
354 *network = (Network) {
355 .filename = TAKE_PTR(fname),
356 .name = TAKE_PTR(name),
357
358 .manager = manager,
359 .n_ref = 1,
360
361 .required_for_online = true,
362 .required_operstate_for_online = LINK_OPERSTATE_DEGRADED,
363 .dhcp = ADDRESS_FAMILY_NO,
364 .dhcp_critical = -1,
365 .dhcp_use_ntp = true,
366 .dhcp_use_dns = true,
367 .dhcp_use_hostname = true,
368 .dhcp_use_routes = true,
369 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
370 .dhcp_send_hostname = true,
371 /* To enable/disable RFC7844 Anonymity Profiles */
372 .dhcp_anonymize = false,
373 .dhcp_route_metric = DHCP_ROUTE_METRIC,
374 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
375 .dhcp_client_identifier = DHCP_CLIENT_ID_DUID,
376 .dhcp_route_table = RT_TABLE_MAIN,
377 .dhcp_route_table_set = false,
378 /* NOTE: from man: UseMTU=... Defaults to false*/
379 .dhcp_use_mtu = false,
380 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
381 .dhcp_use_timezone = false,
382 .rapid_commit = true,
383
384 .dhcp6_use_ntp = true,
385 .dhcp6_use_dns = true,
386
387 .dhcp_server_emit_dns = true,
388 .dhcp_server_emit_ntp = true,
389 .dhcp_server_emit_router = true,
390 .dhcp_server_emit_timezone = true,
391
392 .router_emit_dns = true,
393 .router_emit_domains = true,
394
395 .use_bpdu = -1,
396 .hairpin = -1,
397 .fast_leave = -1,
398 .allow_port_to_be_root = -1,
399 .unicast_flood = -1,
400 .multicast_flood = -1,
401 .multicast_to_unicast = -1,
402 .neighbor_suppression = -1,
403 .learning = -1,
404 .bridge_proxy_arp = -1,
405 .bridge_proxy_arp_wifi = -1,
406 .priority = LINK_BRIDGE_PORT_PRIORITY_INVALID,
407 .multicast_router = _MULTICAST_ROUTER_INVALID,
408
409 .lldp_mode = LLDP_MODE_ROUTERS_ONLY,
410
411 .dns_default_route = -1,
412 .llmnr = RESOLVE_SUPPORT_YES,
413 .mdns = RESOLVE_SUPPORT_NO,
414 .dnssec_mode = _DNSSEC_MODE_INVALID,
415 .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
416
417 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
418 .link_local = _ADDRESS_FAMILY_INVALID,
419
420 .ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO,
421 .ipv6_accept_ra = -1,
422 .ipv6_dad_transmits = -1,
423 .ipv6_hop_limit = -1,
424 .ipv6_proxy_ndp = -1,
425 .duid.type = _DUID_TYPE_INVALID,
426 .proxy_arp = -1,
427 .arp = -1,
428 .multicast = -1,
429 .allmulticast = -1,
430 .ipv6_accept_ra_use_dns = true,
431 .ipv6_accept_ra_use_autonomous_prefix = true,
432 .ipv6_accept_ra_use_onlink_prefix = true,
433 .ipv6_accept_ra_route_table = RT_TABLE_MAIN,
434 .ipv6_accept_ra_route_table_set = false,
435
436 .keep_configuration = _KEEP_CONFIGURATION_INVALID,
437
438 .can_triple_sampling = -1,
439 };
440
441 r = config_parse_many(filename, NETWORK_DIRS, dropin_dirname,
442 "Match\0"
443 "Link\0"
444 "Network\0"
445 "Address\0"
446 "Neighbor\0"
447 "IPv6AddressLabel\0"
448 "RoutingPolicyRule\0"
449 "Route\0"
450 "DHCP\0"
451 "DHCPv4\0" /* compat */
452 "DHCPv6\0"
453 "DHCPServer\0"
454 "IPv6AcceptRA\0"
455 "IPv6NDPProxyAddress\0"
456 "Bridge\0"
457 "BridgeFDB\0"
458 "BridgeVLAN\0"
459 "IPv6PrefixDelegation\0"
460 "IPv6Prefix\0"
461 "CAN\0",
462 config_item_perf_lookup, network_network_gperf_lookup,
463 CONFIG_PARSE_WARN, network);
464 if (r < 0)
465 return r;
466
467 network_apply_anonymize_if_set(network);
468
469 r = network_add_ipv4ll_route(network);
470 if (r < 0)
471 log_warning_errno(r, "%s: Failed to add IPv4LL route, ignoring: %m", network->filename);
472
473 r = network_add_default_route_on_device(network);
474 if (r < 0)
475 log_warning_errno(r, "%s: Failed to add default route on device, ignoring: %m",
476 network->filename);
477
478 r = ordered_hashmap_ensure_allocated(&manager->networks, &string_hash_ops);
479 if (r < 0)
480 return r;
481
482 r = ordered_hashmap_put(manager->networks, network->name, network);
483 if (r < 0)
484 return r;
485
486 if (network_verify(network) < 0)
487 return 0;
488
489 network = NULL;
490 return 0;
491 }
492
493 int network_load(Manager *manager) {
494 _cleanup_strv_free_ char **files = NULL;
495 char **f;
496 int r;
497
498 assert(manager);
499
500 ordered_hashmap_clear_with_destructor(manager->networks, network_unref);
501
502 r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS);
503 if (r < 0)
504 return log_error_errno(r, "Failed to enumerate network files: %m");
505
506 STRV_FOREACH(f, files) {
507 r = network_load_one(manager, *f);
508 if (r < 0)
509 log_error_errno(r, "Failed to load %s, ignoring: %m", *f);
510 }
511
512 return 0;
513 }
514
515 static Network *network_free(Network *network) {
516 IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
517 RoutingPolicyRule *rule;
518 FdbEntry *fdb_entry;
519 Neighbor *neighbor;
520 AddressLabel *label;
521 Prefix *prefix;
522 Address *address;
523 Route *route;
524
525 if (!network)
526 return NULL;
527
528 free(network->filename);
529
530 set_free_free(network->match_mac);
531 strv_free(network->match_path);
532 strv_free(network->match_driver);
533 strv_free(network->match_type);
534 strv_free(network->match_name);
535 strv_free(network->match_property);
536 condition_free_list(network->conditions);
537
538 free(network->description);
539 free(network->dhcp_vendor_class_identifier);
540 strv_free(network->dhcp_user_class);
541 free(network->dhcp_hostname);
542 set_free(network->dhcp_black_listed_ip);
543 free(network->mac);
544
545 strv_free(network->ntp);
546 free(network->dns);
547 ordered_set_free_free(network->search_domains);
548 ordered_set_free_free(network->route_domains);
549 strv_free(network->bind_carrier);
550
551 ordered_set_free_free(network->router_search_domains);
552 free(network->router_dns);
553 set_free_free(network->ndisc_black_listed_prefix);
554
555 free(network->bridge_name);
556 free(network->bond_name);
557 free(network->vrf_name);
558 hashmap_free_free_key(network->stacked_netdev_names);
559 netdev_unref(network->bridge);
560 netdev_unref(network->bond);
561 netdev_unref(network->vrf);
562 hashmap_free_with_destructor(network->stacked_netdevs, netdev_unref);
563
564 while ((route = network->static_routes))
565 route_free(route);
566
567 while ((address = network->static_addresses))
568 address_free(address);
569
570 while ((fdb_entry = network->static_fdb_entries))
571 fdb_entry_free(fdb_entry);
572
573 while ((ipv6_proxy_ndp_address = network->ipv6_proxy_ndp_addresses))
574 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address);
575
576 while ((neighbor = network->neighbors))
577 neighbor_free(neighbor);
578
579 while ((label = network->address_labels))
580 address_label_free(label);
581
582 while ((prefix = network->static_prefixes))
583 prefix_free(prefix);
584
585 while ((rule = network->rules))
586 routing_policy_rule_free(rule);
587
588 hashmap_free(network->addresses_by_section);
589 hashmap_free(network->routes_by_section);
590 hashmap_free(network->fdb_entries_by_section);
591 hashmap_free(network->neighbors_by_section);
592 hashmap_free(network->address_labels_by_section);
593 hashmap_free(network->prefixes_by_section);
594 hashmap_free(network->rules_by_section);
595
596 if (network->manager) {
597 if (network->manager->networks && network->name)
598 ordered_hashmap_remove(network->manager->networks, network->name);
599
600 if (network->manager->duids_requesting_uuid)
601 set_remove(network->manager->duids_requesting_uuid, &network->duid);
602 }
603
604 free(network->name);
605
606 free(network->dhcp_server_timezone);
607 free(network->dhcp_server_dns);
608 free(network->dhcp_server_ntp);
609
610 set_free_free(network->dnssec_negative_trust_anchors);
611
612 return mfree(network);
613 }
614
615 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network, network, network_free);
616
617 int network_get_by_name(Manager *manager, const char *name, Network **ret) {
618 Network *network;
619
620 assert(manager);
621 assert(name);
622 assert(ret);
623
624 network = ordered_hashmap_get(manager->networks, name);
625 if (!network)
626 return -ENOENT;
627
628 *ret = network;
629
630 return 0;
631 }
632
633 int network_get(Manager *manager, sd_device *device,
634 const char *ifname, const struct ether_addr *address,
635 Network **ret) {
636 Network *network;
637 Iterator i;
638
639 assert(manager);
640 assert(ret);
641
642 ORDERED_HASHMAP_FOREACH(network, manager->networks, i)
643 if (net_match_config(network->match_mac, network->match_path, network->match_driver,
644 network->match_type, network->match_name, network->match_property,
645 device, address, ifname)) {
646 if (network->match_name && device) {
647 const char *attr;
648 uint8_t name_assign_type = NET_NAME_UNKNOWN;
649
650 if (sd_device_get_sysattr_value(device, "name_assign_type", &attr) >= 0)
651 (void) safe_atou8(attr, &name_assign_type);
652
653 if (name_assign_type == NET_NAME_ENUM)
654 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
655 ifname, network->filename);
656 else
657 log_debug("%s: found matching network '%s'", ifname, network->filename);
658 } else
659 log_debug("%s: found matching network '%s'", ifname, network->filename);
660
661 *ret = network;
662 return 0;
663 }
664
665 *ret = NULL;
666
667 return -ENOENT;
668 }
669
670 int network_apply(Network *network, Link *link) {
671 assert(network);
672 assert(link);
673
674 link->network = network_ref(network);
675
676 if (network->n_dns > 0 ||
677 !strv_isempty(network->ntp) ||
678 !ordered_set_isempty(network->search_domains) ||
679 !ordered_set_isempty(network->route_domains))
680 link_dirty(link);
681
682 return 0;
683 }
684
685 bool network_has_static_ipv6_configurations(Network *network) {
686 Address *address;
687 Route *route;
688 FdbEntry *fdb;
689 Neighbor *neighbor;
690
691 assert(network);
692
693 LIST_FOREACH(addresses, address, network->static_addresses)
694 if (address->family == AF_INET6)
695 return true;
696
697 LIST_FOREACH(routes, route, network->static_routes)
698 if (route->family == AF_INET6)
699 return true;
700
701 LIST_FOREACH(static_fdb_entries, fdb, network->static_fdb_entries)
702 if (fdb->family == AF_INET6)
703 return true;
704
705 LIST_FOREACH(neighbors, neighbor, network->neighbors)
706 if (neighbor->family == AF_INET6)
707 return true;
708
709 if (!LIST_IS_EMPTY(network->address_labels))
710 return true;
711
712 if (!LIST_IS_EMPTY(network->static_prefixes))
713 return true;
714
715 return false;
716 }
717
718 int config_parse_stacked_netdev(const char *unit,
719 const char *filename,
720 unsigned line,
721 const char *section,
722 unsigned section_line,
723 const char *lvalue,
724 int ltype,
725 const char *rvalue,
726 void *data,
727 void *userdata) {
728 _cleanup_free_ char *name = NULL;
729 NetDevKind kind = ltype;
730 Hashmap **h = data;
731 int r;
732
733 assert(filename);
734 assert(lvalue);
735 assert(rvalue);
736 assert(data);
737 assert(IN_SET(kind,
738 NETDEV_KIND_VLAN, NETDEV_KIND_MACVLAN, NETDEV_KIND_MACVTAP,
739 NETDEV_KIND_IPVLAN, NETDEV_KIND_IPVTAP, NETDEV_KIND_VXLAN,
740 NETDEV_KIND_L2TP, NETDEV_KIND_MACSEC, _NETDEV_KIND_TUNNEL,
741 NETDEV_KIND_XFRM));
742
743 if (!ifname_valid(rvalue)) {
744 log_syntax(unit, LOG_ERR, filename, line, 0,
745 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue, rvalue);
746 return 0;
747 }
748
749 name = strdup(rvalue);
750 if (!name)
751 return log_oom();
752
753 r = hashmap_ensure_allocated(h, &string_hash_ops);
754 if (r < 0)
755 return log_oom();
756
757 r = hashmap_put(*h, name, INT_TO_PTR(kind));
758 if (r < 0)
759 log_syntax(unit, LOG_ERR, filename, line, r,
760 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name);
761 else if (r == 0)
762 log_syntax(unit, LOG_DEBUG, filename, line, r,
763 "NetDev '%s' specified twice, ignoring.", name);
764 else
765 name = NULL;
766
767 return 0;
768 }
769
770 int config_parse_domains(
771 const char *unit,
772 const char *filename,
773 unsigned line,
774 const char *section,
775 unsigned section_line,
776 const char *lvalue,
777 int ltype,
778 const char *rvalue,
779 void *data,
780 void *userdata) {
781
782 const char *p;
783 Network *n = data;
784 int r;
785
786 assert(n);
787 assert(lvalue);
788 assert(rvalue);
789
790 if (isempty(rvalue)) {
791 n->search_domains = ordered_set_free_free(n->search_domains);
792 n->route_domains = ordered_set_free_free(n->route_domains);
793 return 0;
794 }
795
796 p = rvalue;
797 for (;;) {
798 _cleanup_free_ char *w = NULL, *normalized = NULL;
799 const char *domain;
800 bool is_route;
801
802 r = extract_first_word(&p, &w, NULL, 0);
803 if (r < 0) {
804 log_syntax(unit, LOG_ERR, filename, line, r,
805 "Failed to extract search or route domain, ignoring: %s", rvalue);
806 break;
807 }
808 if (r == 0)
809 break;
810
811 is_route = w[0] == '~';
812 domain = is_route ? w + 1 : w;
813
814 if (dns_name_is_root(domain) || streq(domain, "*")) {
815 /* If the root domain appears as is, or the special token "*" is found, we'll
816 * consider this as routing domain, unconditionally. */
817 is_route = true;
818 domain = "."; /* make sure we don't allow empty strings, thus write the root
819 * domain as "." */
820 } else {
821 r = dns_name_normalize(domain, 0, &normalized);
822 if (r < 0) {
823 log_syntax(unit, LOG_ERR, filename, line, r,
824 "'%s' is not a valid domain name, ignoring.", domain);
825 continue;
826 }
827
828 domain = normalized;
829
830 if (is_localhost(domain)) {
831 log_syntax(unit, LOG_ERR, filename, line, 0,
832 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
833 domain);
834 continue;
835 }
836 }
837
838 OrderedSet **set = is_route ? &n->route_domains : &n->search_domains;
839 r = ordered_set_ensure_allocated(set, &string_hash_ops);
840 if (r < 0)
841 return r;
842
843 r = ordered_set_put_strdup(*set, domain);
844 if (r < 0)
845 return log_oom();
846 }
847
848 return 0;
849 }
850
851 int config_parse_ipv6token(
852 const char* unit,
853 const char *filename,
854 unsigned line,
855 const char *section,
856 unsigned section_line,
857 const char *lvalue,
858 int ltype,
859 const char *rvalue,
860 void *data,
861 void *userdata) {
862
863 union in_addr_union buffer;
864 struct in6_addr *token = data;
865 int r;
866
867 assert(filename);
868 assert(lvalue);
869 assert(rvalue);
870 assert(token);
871
872 r = in_addr_from_string(AF_INET6, rvalue, &buffer);
873 if (r < 0) {
874 log_syntax(unit, LOG_ERR, filename, line, r,
875 "Failed to parse IPv6 token, ignoring: %s", rvalue);
876 return 0;
877 }
878
879 if (in_addr_is_null(AF_INET6, &buffer)) {
880 log_syntax(unit, LOG_ERR, filename, line, 0,
881 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue);
882 return 0;
883 }
884
885 if ((buffer.in6.s6_addr32[0] | buffer.in6.s6_addr32[1]) != 0) {
886 log_syntax(unit, LOG_ERR, filename, line, 0,
887 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue);
888 return 0;
889 }
890
891 *token = buffer.in6;
892
893 return 0;
894 }
895
896 static const char* const ipv6_privacy_extensions_table[_IPV6_PRIVACY_EXTENSIONS_MAX] = {
897 [IPV6_PRIVACY_EXTENSIONS_NO] = "no",
898 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC] = "prefer-public",
899 [IPV6_PRIVACY_EXTENSIONS_YES] = "yes",
900 };
901
902 DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions, IPv6PrivacyExtensions);
903
904 int config_parse_ipv6_privacy_extensions(
905 const char* unit,
906 const char *filename,
907 unsigned line,
908 const char *section,
909 unsigned section_line,
910 const char *lvalue,
911 int ltype,
912 const char *rvalue,
913 void *data,
914 void *userdata) {
915
916 IPv6PrivacyExtensions *ipv6_privacy_extensions = data;
917 int k;
918
919 assert(filename);
920 assert(lvalue);
921 assert(rvalue);
922 assert(ipv6_privacy_extensions);
923
924 /* Our enum shall be a superset of booleans, hence first try
925 * to parse as boolean, and then as enum */
926
927 k = parse_boolean(rvalue);
928 if (k > 0)
929 *ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_YES;
930 else if (k == 0)
931 *ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO;
932 else {
933 IPv6PrivacyExtensions s;
934
935 s = ipv6_privacy_extensions_from_string(rvalue);
936 if (s < 0) {
937
938 if (streq(rvalue, "kernel"))
939 s = _IPV6_PRIVACY_EXTENSIONS_INVALID;
940 else {
941 log_syntax(unit, LOG_ERR, filename, line, 0,
942 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue);
943 return 0;
944 }
945 }
946
947 *ipv6_privacy_extensions = s;
948 }
949
950 return 0;
951 }
952
953 int config_parse_hostname(
954 const char *unit,
955 const char *filename,
956 unsigned line,
957 const char *section,
958 unsigned section_line,
959 const char *lvalue,
960 int ltype,
961 const char *rvalue,
962 void *data,
963 void *userdata) {
964
965 _cleanup_free_ char *hn = NULL;
966 char **hostname = data;
967 int r;
968
969 assert(filename);
970 assert(lvalue);
971 assert(rvalue);
972
973 r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &hn, userdata);
974 if (r < 0)
975 return r;
976
977 if (!hostname_is_valid(hn, false)) {
978 log_syntax(unit, LOG_ERR, filename, line, 0,
979 "Hostname is not valid, ignoring assignment: %s", rvalue);
980 return 0;
981 }
982
983 r = dns_name_is_valid(hn);
984 if (r < 0) {
985 log_syntax(unit, LOG_ERR, filename, line, r,
986 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue);
987 return 0;
988 }
989 if (r == 0) {
990 log_syntax(unit, LOG_ERR, filename, line, 0,
991 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue);
992 return 0;
993 }
994
995 return free_and_replace(*hostname, hn);
996 }
997
998 int config_parse_timezone(
999 const char *unit,
1000 const char *filename,
1001 unsigned line,
1002 const char *section,
1003 unsigned section_line,
1004 const char *lvalue,
1005 int ltype,
1006 const char *rvalue,
1007 void *data,
1008 void *userdata) {
1009
1010 _cleanup_free_ char *tz = NULL;
1011 char **datap = data;
1012 int r;
1013
1014 assert(filename);
1015 assert(lvalue);
1016 assert(rvalue);
1017
1018 r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &tz, userdata);
1019 if (r < 0)
1020 return r;
1021
1022 if (!timezone_is_valid(tz, LOG_ERR)) {
1023 log_syntax(unit, LOG_ERR, filename, line, 0,
1024 "Timezone is not valid, ignoring assignment: %s", rvalue);
1025 return 0;
1026 }
1027
1028 return free_and_replace(*datap, tz);
1029 }
1030
1031 int config_parse_dns(
1032 const char *unit,
1033 const char *filename,
1034 unsigned line,
1035 const char *section,
1036 unsigned section_line,
1037 const char *lvalue,
1038 int ltype,
1039 const char *rvalue,
1040 void *data,
1041 void *userdata) {
1042
1043 Network *n = userdata;
1044 int r;
1045
1046 assert(filename);
1047 assert(lvalue);
1048 assert(rvalue);
1049
1050 for (;;) {
1051 _cleanup_free_ char *w = NULL;
1052 union in_addr_union a;
1053 struct in_addr_data *m;
1054 int family;
1055
1056 r = extract_first_word(&rvalue, &w, NULL, 0);
1057 if (r == -ENOMEM)
1058 return log_oom();
1059 if (r < 0) {
1060 log_syntax(unit, LOG_ERR, filename, line, r,
1061 "Invalid syntax, ignoring: %s", rvalue);
1062 break;
1063 }
1064 if (r == 0)
1065 break;
1066
1067 r = in_addr_from_string_auto(w, &family, &a);
1068 if (r < 0) {
1069 log_syntax(unit, LOG_ERR, filename, line, r,
1070 "Failed to parse dns server address, ignoring: %s", w);
1071 continue;
1072 }
1073
1074 m = reallocarray(n->dns, n->n_dns + 1, sizeof(struct in_addr_data));
1075 if (!m)
1076 return log_oom();
1077
1078 m[n->n_dns++] = (struct in_addr_data) {
1079 .family = family,
1080 .address = a,
1081 };
1082
1083 n->dns = m;
1084 }
1085
1086 return 0;
1087 }
1088
1089 int config_parse_dnssec_negative_trust_anchors(
1090 const char *unit,
1091 const char *filename,
1092 unsigned line,
1093 const char *section,
1094 unsigned section_line,
1095 const char *lvalue,
1096 int ltype,
1097 const char *rvalue,
1098 void *data,
1099 void *userdata) {
1100
1101 const char *p = rvalue;
1102 Network *n = data;
1103 int r;
1104
1105 assert(n);
1106 assert(lvalue);
1107 assert(rvalue);
1108
1109 if (isempty(rvalue)) {
1110 n->dnssec_negative_trust_anchors = set_free_free(n->dnssec_negative_trust_anchors);
1111 return 0;
1112 }
1113
1114 for (;;) {
1115 _cleanup_free_ char *w = NULL;
1116
1117 r = extract_first_word(&p, &w, NULL, 0);
1118 if (r < 0) {
1119 log_syntax(unit, LOG_ERR, filename, line, r,
1120 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue);
1121 break;
1122 }
1123 if (r == 0)
1124 break;
1125
1126 r = dns_name_is_valid(w);
1127 if (r <= 0) {
1128 log_syntax(unit, LOG_ERR, filename, line, r,
1129 "%s is not a valid domain name, ignoring.", w);
1130 continue;
1131 }
1132
1133 r = set_ensure_allocated(&n->dnssec_negative_trust_anchors, &dns_name_hash_ops);
1134 if (r < 0)
1135 return log_oom();
1136
1137 r = set_put(n->dnssec_negative_trust_anchors, w);
1138 if (r < 0)
1139 return log_oom();
1140 if (r > 0)
1141 w = NULL;
1142 }
1143
1144 return 0;
1145 }
1146
1147 int config_parse_ntp(
1148 const char *unit,
1149 const char *filename,
1150 unsigned line,
1151 const char *section,
1152 unsigned section_line,
1153 const char *lvalue,
1154 int ltype,
1155 const char *rvalue,
1156 void *data,
1157 void *userdata) {
1158
1159 char ***l = data;
1160 int r;
1161
1162 assert(l);
1163 assert(lvalue);
1164 assert(rvalue);
1165
1166 if (isempty(rvalue)) {
1167 *l = strv_free(*l);
1168 return 0;
1169 }
1170
1171 for (;;) {
1172 _cleanup_free_ char *w = NULL;
1173
1174 r = extract_first_word(&rvalue, &w, NULL, 0);
1175 if (r == -ENOMEM)
1176 return log_oom();
1177 if (r < 0) {
1178 log_syntax(unit, LOG_ERR, filename, line, r,
1179 "Failed to extract NTP server name, ignoring: %s", rvalue);
1180 break;
1181 }
1182 if (r == 0)
1183 break;
1184
1185 r = dns_name_is_valid_or_address(w);
1186 if (r <= 0) {
1187 log_syntax(unit, LOG_ERR, filename, line, r,
1188 "%s is not a valid domain name or IP address, ignoring.", w);
1189 continue;
1190 }
1191
1192 if (strv_length(*l) > MAX_NTP_SERVERS) {
1193 log_syntax(unit, LOG_WARNING, filename, line, 0,
1194 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1195 MAX_NTP_SERVERS, w);
1196 break;
1197 }
1198
1199 r = strv_consume(l, TAKE_PTR(w));
1200 if (r < 0)
1201 return log_oom();
1202 }
1203
1204 return 0;
1205 }
1206
1207 int config_parse_required_for_online(
1208 const char *unit,
1209 const char *filename,
1210 unsigned line,
1211 const char *section,
1212 unsigned section_line,
1213 const char *lvalue,
1214 int ltype,
1215 const char *rvalue,
1216 void *data,
1217 void *userdata) {
1218
1219 Network *network = data;
1220 LinkOperationalState s;
1221 bool required = true;
1222 int r;
1223
1224 if (isempty(rvalue)) {
1225 network->required_for_online = true;
1226 network->required_operstate_for_online = LINK_OPERSTATE_DEGRADED;
1227 return 0;
1228 }
1229
1230 s = link_operstate_from_string(rvalue);
1231 if (s < 0) {
1232 r = parse_boolean(rvalue);
1233 if (r < 0) {
1234 log_syntax(unit, LOG_ERR, filename, line, r,
1235 "Failed to parse %s= setting, ignoring assignment: %s",
1236 lvalue, rvalue);
1237 return 0;
1238 }
1239
1240 required = r;
1241 s = LINK_OPERSTATE_DEGRADED;
1242 }
1243
1244 network->required_for_online = required;
1245 network->required_operstate_for_online = s;
1246
1247 return 0;
1248 }
1249
1250 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration, keep_configuration, KeepConfiguration,
1251 "Failed to parse KeepConfiguration= setting");
1252
1253 static const char* const keep_configuration_table[_KEEP_CONFIGURATION_MAX] = {
1254 [KEEP_CONFIGURATION_NO] = "no",
1255 [KEEP_CONFIGURATION_DHCP_ON_STOP] = "dhcp-on-stop",
1256 [KEEP_CONFIGURATION_DHCP] = "dhcp",
1257 [KEEP_CONFIGURATION_STATIC] = "static",
1258 [KEEP_CONFIGURATION_YES] = "yes",
1259 };
1260
1261 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration, KeepConfiguration, KEEP_CONFIGURATION_YES);