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