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