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