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