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