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