]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-network.c
Merge pull request #15365 from poettering/remount-fs-pstore-fix
[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 "LLDP\0"
489 "TrafficControlQueueingDiscipline\0"
490 "CAN\0"
491 "QDisc\0"
492 "BFIFO\0"
493 "CAKE\0"
494 "ControlledDelay\0"
495 "DeficitRoundRobinScheduler\0"
496 "DeficitRoundRobinSchedulerClass\0"
497 "PFIFO\0"
498 "PFIFOFast\0"
499 "PFIFOHeadDrop\0"
500 "FairQueueing\0"
501 "FairQueueingControlledDelay\0"
502 "GenericRandomEarlyDetection\0"
503 "HeavyHitterFilter\0"
504 "HierarchyTokenBucket\0"
505 "HierarchyTokenBucketClass\0"
506 "NetworkEmulator\0"
507 "PIE\0"
508 "StochasticFairBlue\0"
509 "StochasticFairnessQueueing\0"
510 "TokenBucketFilter\0"
511 "TrivialLinkEqualizer\0",
512 config_item_perf_lookup, network_network_gperf_lookup,
513 CONFIG_PARSE_WARN, network);
514 if (r < 0)
515 return r;
516
517 network_apply_anonymize_if_set(network);
518
519 r = network_add_ipv4ll_route(network);
520 if (r < 0)
521 log_warning_errno(r, "%s: Failed to add IPv4LL route, ignoring: %m", network->filename);
522
523 r = network_add_default_route_on_device(network);
524 if (r < 0)
525 log_warning_errno(r, "%s: Failed to add default route on device, ignoring: %m",
526 network->filename);
527
528 struct stat stats;
529 if (stat(filename, &stats) < 0)
530 return -errno;
531 network->timestamp = timespec_load(&stats.st_mtim);
532
533 if (network_verify(network) < 0)
534 /* Ignore .network files that do not match the conditions. */
535 return 0;
536
537 r = ordered_hashmap_ensure_allocated(networks, &string_hash_ops);
538 if (r < 0)
539 return r;
540
541 r = ordered_hashmap_put(*networks, network->name, network);
542 if (r < 0)
543 return r;
544
545 network = NULL;
546 return 0;
547 }
548
549 int network_load(Manager *manager, OrderedHashmap **networks) {
550 _cleanup_strv_free_ char **files = NULL;
551 char **f;
552 int r;
553
554 assert(manager);
555
556 ordered_hashmap_clear_with_destructor(*networks, network_unref);
557
558 r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS);
559 if (r < 0)
560 return log_error_errno(r, "Failed to enumerate network files: %m");
561
562 STRV_FOREACH(f, files) {
563 r = network_load_one(manager, networks, *f);
564 if (r < 0)
565 log_error_errno(r, "Failed to load %s, ignoring: %m", *f);
566 }
567
568 return 0;
569 }
570
571 int network_reload(Manager *manager) {
572 OrderedHashmap *new_networks = NULL;
573 Network *n, *old;
574 Iterator i;
575 int r;
576
577 assert(manager);
578
579 r = network_load(manager, &new_networks);
580 if (r < 0)
581 goto failure;
582
583 ORDERED_HASHMAP_FOREACH(n, new_networks, i) {
584 r = network_get_by_name(manager, n->name, &old);
585 if (r < 0)
586 continue; /* The .network file is new. */
587
588 if (n->timestamp != old->timestamp)
589 continue; /* The .network file is modified. */
590
591 if (!streq(n->filename, old->filename))
592 continue;
593
594 r = ordered_hashmap_replace(new_networks, old->name, old);
595 if (r < 0)
596 goto failure;
597
598 network_ref(old);
599 network_unref(n);
600 }
601
602 ordered_hashmap_free_with_destructor(manager->networks, network_unref);
603 manager->networks = new_networks;
604
605 return 0;
606
607 failure:
608 ordered_hashmap_free_with_destructor(new_networks, network_unref);
609
610 return r;
611 }
612
613 static Network *network_free(Network *network) {
614 IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
615 RoutePrefix *route_prefix;
616 RoutingPolicyRule *rule;
617 AddressLabel *label;
618 FdbEntry *fdb_entry;
619 Neighbor *neighbor;
620 Address *address;
621 NextHop *nexthop;
622 Prefix *prefix;
623 Route *route;
624
625 if (!network)
626 return NULL;
627
628 free(network->filename);
629
630 set_free_free(network->match_mac);
631 set_free_free(network->match_permanent_mac);
632 strv_free(network->match_path);
633 strv_free(network->match_driver);
634 strv_free(network->match_type);
635 strv_free(network->match_name);
636 strv_free(network->match_property);
637 strv_free(network->match_wlan_iftype);
638 strv_free(network->match_ssid);
639 set_free_free(network->match_bssid);
640 condition_free_list(network->conditions);
641
642 free(network->description);
643 free(network->dhcp_vendor_class_identifier);
644 free(network->dhcp_mudurl);
645 strv_free(network->dhcp_user_class);
646 free(network->dhcp_hostname);
647 set_free(network->dhcp_black_listed_ip);
648 set_free(network->dhcp_request_options);
649 free(network->mac);
650 free(network->dhcp6_mudurl);
651
652 if (network->dhcp_acd)
653 sd_ipv4acd_unref(network->dhcp_acd);
654
655 strv_free(network->ntp);
656 free(network->dns);
657 strv_free(network->sip);
658 strv_free(network->smtp);
659 ordered_set_free_free(network->search_domains);
660 ordered_set_free_free(network->route_domains);
661 strv_free(network->bind_carrier);
662
663 ordered_set_free_free(network->router_search_domains);
664 free(network->router_dns);
665 set_free_free(network->ndisc_black_listed_prefix);
666
667 free(network->bridge_name);
668 free(network->bond_name);
669 free(network->vrf_name);
670 hashmap_free_free_key(network->stacked_netdev_names);
671 netdev_unref(network->bridge);
672 netdev_unref(network->bond);
673 netdev_unref(network->vrf);
674 hashmap_free_with_destructor(network->stacked_netdevs, netdev_unref);
675
676 while ((route = network->static_routes))
677 route_free(route);
678
679 while ((nexthop = network->static_nexthops))
680 nexthop_free(nexthop);
681
682 while ((address = network->static_addresses))
683 address_free(address);
684
685 while ((fdb_entry = network->static_fdb_entries))
686 fdb_entry_free(fdb_entry);
687
688 while ((ipv6_proxy_ndp_address = network->ipv6_proxy_ndp_addresses))
689 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address);
690
691 while ((neighbor = network->neighbors))
692 neighbor_free(neighbor);
693
694 while ((label = network->address_labels))
695 address_label_free(label);
696
697 while ((prefix = network->static_prefixes))
698 prefix_free(prefix);
699
700 while ((route_prefix = network->static_route_prefixes))
701 route_prefix_free(route_prefix);
702
703 while ((rule = network->rules))
704 routing_policy_rule_free(rule);
705
706 hashmap_free(network->addresses_by_section);
707 hashmap_free(network->routes_by_section);
708 hashmap_free(network->nexthops_by_section);
709 hashmap_free(network->fdb_entries_by_section);
710 hashmap_free(network->neighbors_by_section);
711 hashmap_free(network->address_labels_by_section);
712 hashmap_free(network->prefixes_by_section);
713 hashmap_free(network->route_prefixes_by_section);
714 hashmap_free(network->rules_by_section);
715 ordered_hashmap_free_with_destructor(network->tc_by_section, traffic_control_free);
716
717 if (network->manager &&
718 network->manager->duids_requesting_uuid)
719 set_remove(network->manager->duids_requesting_uuid, &network->duid);
720
721 free(network->name);
722
723 free(network->dhcp_server_timezone);
724 free(network->dhcp_server_dns);
725 free(network->dhcp_server_ntp);
726 free(network->dhcp_server_sip);
727
728 set_free_free(network->dnssec_negative_trust_anchors);
729
730 free(network->lldp_mud);
731
732 ordered_hashmap_free(network->dhcp_client_send_options);
733 ordered_hashmap_free(network->dhcp_client_send_vendor_options);
734 ordered_hashmap_free(network->dhcp_server_send_options);
735 ordered_hashmap_free(network->dhcp_server_send_vendor_options);
736 ordered_hashmap_free(network->ipv6_tokens);
737
738 return mfree(network);
739 }
740
741 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network, network, network_free);
742
743 int network_get_by_name(Manager *manager, const char *name, Network **ret) {
744 Network *network;
745
746 assert(manager);
747 assert(name);
748 assert(ret);
749
750 network = ordered_hashmap_get(manager->networks, name);
751 if (!network)
752 return -ENOENT;
753
754 *ret = network;
755
756 return 0;
757 }
758
759 int network_get(Manager *manager, unsigned short iftype, sd_device *device,
760 const char *ifname, char * const *alternative_names,
761 const struct ether_addr *address, const struct ether_addr *permanent_address,
762 enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid,
763 Network **ret) {
764 Network *network;
765 Iterator i;
766
767 assert(manager);
768 assert(ret);
769
770 ORDERED_HASHMAP_FOREACH(network, manager->networks, i)
771 if (net_match_config(network->match_mac, network->match_permanent_mac,
772 network->match_path, network->match_driver,
773 network->match_type, network->match_name, network->match_property,
774 network->match_wlan_iftype, network->match_ssid, network->match_bssid,
775 iftype, device, address, permanent_address,
776 ifname, alternative_names, wlan_iftype, ssid, bssid)) {
777 if (network->match_name && device) {
778 const char *attr;
779 uint8_t name_assign_type = NET_NAME_UNKNOWN;
780
781 if (sd_device_get_sysattr_value(device, "name_assign_type", &attr) >= 0)
782 (void) safe_atou8(attr, &name_assign_type);
783
784 if (name_assign_type == NET_NAME_ENUM)
785 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
786 ifname, network->filename);
787 else
788 log_debug("%s: found matching network '%s'", ifname, network->filename);
789 } else
790 log_debug("%s: found matching network '%s'", ifname, network->filename);
791
792 *ret = network;
793 return 0;
794 }
795
796 *ret = NULL;
797
798 return -ENOENT;
799 }
800
801 int network_apply(Network *network, Link *link) {
802 assert(network);
803 assert(link);
804
805 link->network = network_ref(network);
806
807 if (network->n_dns > 0 ||
808 !strv_isempty(network->ntp) ||
809 !ordered_set_isempty(network->search_domains) ||
810 !ordered_set_isempty(network->route_domains))
811 link_dirty(link);
812
813 return 0;
814 }
815
816 bool network_has_static_ipv6_configurations(Network *network) {
817 Address *address;
818 Route *route;
819 FdbEntry *fdb;
820 Neighbor *neighbor;
821
822 assert(network);
823
824 LIST_FOREACH(addresses, address, network->static_addresses)
825 if (address->family == AF_INET6)
826 return true;
827
828 LIST_FOREACH(routes, route, network->static_routes)
829 if (route->family == AF_INET6)
830 return true;
831
832 LIST_FOREACH(static_fdb_entries, fdb, network->static_fdb_entries)
833 if (fdb->family == AF_INET6)
834 return true;
835
836 LIST_FOREACH(neighbors, neighbor, network->neighbors)
837 if (neighbor->family == AF_INET6)
838 return true;
839
840 if (!LIST_IS_EMPTY(network->address_labels))
841 return true;
842
843 if (!LIST_IS_EMPTY(network->static_prefixes))
844 return true;
845
846 return false;
847 }
848
849 int config_parse_stacked_netdev(const char *unit,
850 const char *filename,
851 unsigned line,
852 const char *section,
853 unsigned section_line,
854 const char *lvalue,
855 int ltype,
856 const char *rvalue,
857 void *data,
858 void *userdata) {
859 _cleanup_free_ char *name = NULL;
860 NetDevKind kind = ltype;
861 Hashmap **h = data;
862 int r;
863
864 assert(filename);
865 assert(lvalue);
866 assert(rvalue);
867 assert(data);
868 assert(IN_SET(kind,
869 NETDEV_KIND_VLAN, NETDEV_KIND_MACVLAN, NETDEV_KIND_MACVTAP,
870 NETDEV_KIND_IPVLAN, NETDEV_KIND_IPVTAP, NETDEV_KIND_VXLAN,
871 NETDEV_KIND_L2TP, NETDEV_KIND_MACSEC, _NETDEV_KIND_TUNNEL,
872 NETDEV_KIND_XFRM));
873
874 if (!ifname_valid(rvalue)) {
875 log_syntax(unit, LOG_ERR, filename, line, 0,
876 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue, rvalue);
877 return 0;
878 }
879
880 name = strdup(rvalue);
881 if (!name)
882 return log_oom();
883
884 r = hashmap_ensure_allocated(h, &string_hash_ops);
885 if (r < 0)
886 return log_oom();
887
888 r = hashmap_put(*h, name, INT_TO_PTR(kind));
889 if (r < 0)
890 log_syntax(unit, LOG_ERR, filename, line, r,
891 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name);
892 else if (r == 0)
893 log_syntax(unit, LOG_DEBUG, filename, line, r,
894 "NetDev '%s' specified twice, ignoring.", name);
895 else
896 name = NULL;
897
898 return 0;
899 }
900
901 int config_parse_domains(
902 const char *unit,
903 const char *filename,
904 unsigned line,
905 const char *section,
906 unsigned section_line,
907 const char *lvalue,
908 int ltype,
909 const char *rvalue,
910 void *data,
911 void *userdata) {
912
913 const char *p;
914 Network *n = data;
915 int r;
916
917 assert(n);
918 assert(lvalue);
919 assert(rvalue);
920
921 if (isempty(rvalue)) {
922 n->search_domains = ordered_set_free_free(n->search_domains);
923 n->route_domains = ordered_set_free_free(n->route_domains);
924 return 0;
925 }
926
927 p = rvalue;
928 for (;;) {
929 _cleanup_free_ char *w = NULL, *normalized = NULL;
930 const char *domain;
931 bool is_route;
932
933 r = extract_first_word(&p, &w, NULL, 0);
934 if (r < 0) {
935 log_syntax(unit, LOG_ERR, filename, line, r,
936 "Failed to extract search or route domain, ignoring: %s", rvalue);
937 break;
938 }
939 if (r == 0)
940 break;
941
942 is_route = w[0] == '~';
943 domain = is_route ? w + 1 : w;
944
945 if (dns_name_is_root(domain) || streq(domain, "*")) {
946 /* If the root domain appears as is, or the special token "*" is found, we'll
947 * consider this as routing domain, unconditionally. */
948 is_route = true;
949 domain = "."; /* make sure we don't allow empty strings, thus write the root
950 * domain as "." */
951 } else {
952 r = dns_name_normalize(domain, 0, &normalized);
953 if (r < 0) {
954 log_syntax(unit, LOG_ERR, filename, line, r,
955 "'%s' is not a valid domain name, ignoring.", domain);
956 continue;
957 }
958
959 domain = normalized;
960
961 if (is_localhost(domain)) {
962 log_syntax(unit, LOG_ERR, filename, line, 0,
963 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
964 domain);
965 continue;
966 }
967 }
968
969 OrderedSet **set = is_route ? &n->route_domains : &n->search_domains;
970 r = ordered_set_ensure_allocated(set, &string_hash_ops);
971 if (r < 0)
972 return r;
973
974 r = ordered_set_put_strdup(*set, domain);
975 if (r < 0)
976 return log_oom();
977 }
978
979 return 0;
980 }
981
982 int config_parse_ipv6token(
983 const char* unit,
984 const char *filename,
985 unsigned line,
986 const char *section,
987 unsigned section_line,
988 const char *lvalue,
989 int ltype,
990 const char *rvalue,
991 void *data,
992 void *userdata) {
993
994 union in_addr_union buffer;
995 struct in6_addr *token = data;
996 int r;
997
998 assert(filename);
999 assert(lvalue);
1000 assert(rvalue);
1001 assert(token);
1002
1003 r = in_addr_from_string(AF_INET6, rvalue, &buffer);
1004 if (r < 0) {
1005 log_syntax(unit, LOG_ERR, filename, line, r,
1006 "Failed to parse IPv6 token, ignoring: %s", rvalue);
1007 return 0;
1008 }
1009
1010 if (in_addr_is_null(AF_INET6, &buffer)) {
1011 log_syntax(unit, LOG_ERR, filename, line, 0,
1012 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue);
1013 return 0;
1014 }
1015
1016 if ((buffer.in6.s6_addr32[0] | buffer.in6.s6_addr32[1]) != 0) {
1017 log_syntax(unit, LOG_ERR, filename, line, 0,
1018 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue);
1019 return 0;
1020 }
1021
1022 *token = buffer.in6;
1023
1024 return 0;
1025 }
1026
1027 static const char* const ipv6_privacy_extensions_table[_IPV6_PRIVACY_EXTENSIONS_MAX] = {
1028 [IPV6_PRIVACY_EXTENSIONS_NO] = "no",
1029 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC] = "prefer-public",
1030 [IPV6_PRIVACY_EXTENSIONS_YES] = "yes",
1031 };
1032
1033 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions, IPv6PrivacyExtensions,
1034 IPV6_PRIVACY_EXTENSIONS_YES);
1035
1036 int config_parse_ipv6_privacy_extensions(
1037 const char* unit,
1038 const char *filename,
1039 unsigned line,
1040 const char *section,
1041 unsigned section_line,
1042 const char *lvalue,
1043 int ltype,
1044 const char *rvalue,
1045 void *data,
1046 void *userdata) {
1047
1048 IPv6PrivacyExtensions s, *ipv6_privacy_extensions = data;
1049
1050 assert(filename);
1051 assert(lvalue);
1052 assert(rvalue);
1053 assert(ipv6_privacy_extensions);
1054
1055 s = ipv6_privacy_extensions_from_string(rvalue);
1056 if (s < 0) {
1057 if (streq(rvalue, "kernel"))
1058 s = _IPV6_PRIVACY_EXTENSIONS_INVALID;
1059 else {
1060 log_syntax(unit, LOG_ERR, filename, line, 0,
1061 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue);
1062 return 0;
1063 }
1064 }
1065
1066 *ipv6_privacy_extensions = s;
1067
1068 return 0;
1069 }
1070
1071 int config_parse_hostname(
1072 const char *unit,
1073 const char *filename,
1074 unsigned line,
1075 const char *section,
1076 unsigned section_line,
1077 const char *lvalue,
1078 int ltype,
1079 const char *rvalue,
1080 void *data,
1081 void *userdata) {
1082
1083 _cleanup_free_ char *hn = NULL;
1084 char **hostname = data;
1085 int r;
1086
1087 assert(filename);
1088 assert(lvalue);
1089 assert(rvalue);
1090
1091 r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &hn, userdata);
1092 if (r < 0)
1093 return r;
1094
1095 if (!hostname_is_valid(hn, false)) {
1096 log_syntax(unit, LOG_ERR, filename, line, 0,
1097 "Hostname is not valid, ignoring assignment: %s", rvalue);
1098 return 0;
1099 }
1100
1101 r = dns_name_is_valid(hn);
1102 if (r < 0) {
1103 log_syntax(unit, LOG_ERR, filename, line, r,
1104 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue);
1105 return 0;
1106 }
1107 if (r == 0) {
1108 log_syntax(unit, LOG_ERR, filename, line, 0,
1109 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue);
1110 return 0;
1111 }
1112
1113 return free_and_replace(*hostname, hn);
1114 }
1115
1116 int config_parse_timezone(
1117 const char *unit,
1118 const char *filename,
1119 unsigned line,
1120 const char *section,
1121 unsigned section_line,
1122 const char *lvalue,
1123 int ltype,
1124 const char *rvalue,
1125 void *data,
1126 void *userdata) {
1127
1128 _cleanup_free_ char *tz = NULL;
1129 char **datap = data;
1130 int r;
1131
1132 assert(filename);
1133 assert(lvalue);
1134 assert(rvalue);
1135
1136 r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &tz, userdata);
1137 if (r < 0)
1138 return r;
1139
1140 if (!timezone_is_valid(tz, LOG_ERR)) {
1141 log_syntax(unit, LOG_ERR, filename, line, 0,
1142 "Timezone is not valid, ignoring assignment: %s", rvalue);
1143 return 0;
1144 }
1145
1146 return free_and_replace(*datap, tz);
1147 }
1148
1149 int config_parse_dns(
1150 const char *unit,
1151 const char *filename,
1152 unsigned line,
1153 const char *section,
1154 unsigned section_line,
1155 const char *lvalue,
1156 int ltype,
1157 const char *rvalue,
1158 void *data,
1159 void *userdata) {
1160
1161 Network *n = userdata;
1162 int r;
1163
1164 assert(filename);
1165 assert(lvalue);
1166 assert(rvalue);
1167
1168 for (;;) {
1169 _cleanup_free_ char *w = NULL;
1170 union in_addr_union a;
1171 struct in_addr_data *m;
1172 int family;
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 "Invalid syntax, ignoring: %s", rvalue);
1180 break;
1181 }
1182 if (r == 0)
1183 break;
1184
1185 r = in_addr_from_string_auto(w, &family, &a);
1186 if (r < 0) {
1187 log_syntax(unit, LOG_ERR, filename, line, r,
1188 "Failed to parse dns server address, ignoring: %s", w);
1189 continue;
1190 }
1191
1192 m = reallocarray(n->dns, n->n_dns + 1, sizeof(struct in_addr_data));
1193 if (!m)
1194 return log_oom();
1195
1196 m[n->n_dns++] = (struct in_addr_data) {
1197 .family = family,
1198 .address = a,
1199 };
1200
1201 n->dns = m;
1202 }
1203
1204 return 0;
1205 }
1206
1207 int config_parse_dnssec_negative_trust_anchors(
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 const char *p = rvalue;
1220 Network *n = data;
1221 int r;
1222
1223 assert(n);
1224 assert(lvalue);
1225 assert(rvalue);
1226
1227 if (isempty(rvalue)) {
1228 n->dnssec_negative_trust_anchors = set_free_free(n->dnssec_negative_trust_anchors);
1229 return 0;
1230 }
1231
1232 for (;;) {
1233 _cleanup_free_ char *w = NULL;
1234
1235 r = extract_first_word(&p, &w, NULL, 0);
1236 if (r < 0) {
1237 log_syntax(unit, LOG_ERR, filename, line, r,
1238 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue);
1239 break;
1240 }
1241 if (r == 0)
1242 break;
1243
1244 r = dns_name_is_valid(w);
1245 if (r <= 0) {
1246 log_syntax(unit, LOG_ERR, filename, line, r,
1247 "%s is not a valid domain name, ignoring.", w);
1248 continue;
1249 }
1250
1251 r = set_ensure_allocated(&n->dnssec_negative_trust_anchors, &dns_name_hash_ops);
1252 if (r < 0)
1253 return log_oom();
1254
1255 r = set_put(n->dnssec_negative_trust_anchors, w);
1256 if (r < 0)
1257 return log_oom();
1258 if (r > 0)
1259 w = NULL;
1260 }
1261
1262 return 0;
1263 }
1264
1265 int config_parse_ntp(
1266 const char *unit,
1267 const char *filename,
1268 unsigned line,
1269 const char *section,
1270 unsigned section_line,
1271 const char *lvalue,
1272 int ltype,
1273 const char *rvalue,
1274 void *data,
1275 void *userdata) {
1276
1277 char ***l = data;
1278 int r;
1279
1280 assert(l);
1281 assert(lvalue);
1282 assert(rvalue);
1283
1284 if (isempty(rvalue)) {
1285 *l = strv_free(*l);
1286 return 0;
1287 }
1288
1289 for (;;) {
1290 _cleanup_free_ char *w = NULL;
1291
1292 r = extract_first_word(&rvalue, &w, NULL, 0);
1293 if (r == -ENOMEM)
1294 return log_oom();
1295 if (r < 0) {
1296 log_syntax(unit, LOG_ERR, filename, line, r,
1297 "Failed to extract NTP server name, ignoring: %s", rvalue);
1298 break;
1299 }
1300 if (r == 0)
1301 break;
1302
1303 r = dns_name_is_valid_or_address(w);
1304 if (r <= 0) {
1305 log_syntax(unit, LOG_ERR, filename, line, r,
1306 "%s is not a valid domain name or IP address, ignoring.", w);
1307 continue;
1308 }
1309
1310 if (strv_length(*l) > MAX_NTP_SERVERS) {
1311 log_syntax(unit, LOG_WARNING, filename, line, 0,
1312 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1313 MAX_NTP_SERVERS, w);
1314 break;
1315 }
1316
1317 r = strv_consume(l, TAKE_PTR(w));
1318 if (r < 0)
1319 return log_oom();
1320 }
1321
1322 return 0;
1323 }
1324
1325 int config_parse_required_for_online(
1326 const char *unit,
1327 const char *filename,
1328 unsigned line,
1329 const char *section,
1330 unsigned section_line,
1331 const char *lvalue,
1332 int ltype,
1333 const char *rvalue,
1334 void *data,
1335 void *userdata) {
1336
1337 Network *network = data;
1338 LinkOperationalStateRange range;
1339 bool required = true;
1340 int r;
1341
1342 if (isempty(rvalue)) {
1343 network->required_for_online = true;
1344 network->required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT;
1345 return 0;
1346 }
1347
1348 r = parse_operational_state_range(rvalue, &range);
1349 if (r < 0) {
1350 r = parse_boolean(rvalue);
1351 if (r < 0) {
1352 log_syntax(unit, LOG_ERR, filename, line, r,
1353 "Failed to parse %s= setting, ignoring assignment: %s",
1354 lvalue, rvalue);
1355 return 0;
1356 }
1357
1358 required = r;
1359 range = LINK_OPERSTATE_RANGE_DEFAULT;
1360 }
1361
1362 network->required_for_online = required;
1363 network->required_operstate_for_online = range;
1364
1365 return 0;
1366 }
1367
1368 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration, keep_configuration, KeepConfiguration,
1369 "Failed to parse KeepConfiguration= setting");
1370
1371 static const char* const keep_configuration_table[_KEEP_CONFIGURATION_MAX] = {
1372 [KEEP_CONFIGURATION_NO] = "no",
1373 [KEEP_CONFIGURATION_DHCP_ON_STOP] = "dhcp-on-stop",
1374 [KEEP_CONFIGURATION_DHCP] = "dhcp",
1375 [KEEP_CONFIGURATION_STATIC] = "static",
1376 [KEEP_CONFIGURATION_YES] = "yes",
1377 };
1378
1379 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration, KeepConfiguration, KEEP_CONFIGURATION_YES);