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