]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-network.c
network: Fix split in `SendOption=` on client and server
[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 .dhcp_use_gateway = true,
388 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
389 .dhcp_send_hostname = true,
390 .dhcp_send_release = true,
391 /* To enable/disable RFC7844 Anonymity Profiles */
392 .dhcp_anonymize = false,
393 .dhcp_route_metric = DHCP_ROUTE_METRIC,
394 /* NOTE: this var might be overwritten by network_apply_anonymize_if_set */
395 .dhcp_client_identifier = DHCP_CLIENT_ID_DUID,
396 .dhcp_route_table = RT_TABLE_MAIN,
397 .dhcp_route_table_set = false,
398 /* NOTE: from man: UseMTU=... Defaults to false*/
399 .dhcp_use_mtu = false,
400 /* NOTE: from man: UseTimezone=... Defaults to "no".*/
401 .dhcp_use_timezone = false,
402 .rapid_commit = true,
403
404 .dhcp6_use_ntp = true,
405 .dhcp6_use_dns = true,
406
407 .dhcp_server_emit_dns = true,
408 .dhcp_server_emit_ntp = true,
409 .dhcp_server_emit_sip = true,
410 .dhcp_server_emit_router = true,
411 .dhcp_server_emit_timezone = true,
412
413 .router_emit_dns = true,
414 .router_emit_domains = true,
415
416 .use_bpdu = -1,
417 .hairpin = -1,
418 .fast_leave = -1,
419 .allow_port_to_be_root = -1,
420 .unicast_flood = -1,
421 .multicast_flood = -1,
422 .multicast_to_unicast = -1,
423 .neighbor_suppression = -1,
424 .learning = -1,
425 .bridge_proxy_arp = -1,
426 .bridge_proxy_arp_wifi = -1,
427 .priority = LINK_BRIDGE_PORT_PRIORITY_INVALID,
428 .multicast_router = _MULTICAST_ROUTER_INVALID,
429
430 .lldp_mode = LLDP_MODE_ROUTERS_ONLY,
431
432 .dns_default_route = -1,
433 .llmnr = RESOLVE_SUPPORT_YES,
434 .mdns = RESOLVE_SUPPORT_NO,
435 .dnssec_mode = _DNSSEC_MODE_INVALID,
436 .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
437
438 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
439 .link_local = _ADDRESS_FAMILY_INVALID,
440
441 .ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO,
442 .ipv6_accept_ra = -1,
443 .ipv6_dad_transmits = -1,
444 .ipv6_hop_limit = -1,
445 .ipv6_proxy_ndp = -1,
446 .duid.type = _DUID_TYPE_INVALID,
447 .proxy_arp = -1,
448 .arp = -1,
449 .multicast = -1,
450 .allmulticast = -1,
451 .ipv6_accept_ra_use_dns = true,
452 .ipv6_accept_ra_use_autonomous_prefix = true,
453 .ipv6_accept_ra_use_onlink_prefix = true,
454 .ipv6_accept_ra_route_table = RT_TABLE_MAIN,
455 .ipv6_accept_ra_route_table_set = false,
456 .ipv6_accept_ra_start_dhcp6_client = true,
457
458 .keep_configuration = _KEEP_CONFIGURATION_INVALID,
459
460 .can_triple_sampling = -1,
461 .can_termination = -1,
462 .ip_service_type = -1,
463 };
464
465 r = config_parse_many(filename, NETWORK_DIRS, dropin_dirname,
466 "Match\0"
467 "Link\0"
468 "Network\0"
469 "Address\0"
470 "Neighbor\0"
471 "IPv6AddressLabel\0"
472 "RoutingPolicyRule\0"
473 "Route\0"
474 "NextHop\0"
475 "DHCP\0" /* compat */
476 "DHCPv4\0"
477 "DHCPv6\0"
478 "DHCPServer\0"
479 "IPv6AcceptRA\0"
480 "IPv6NDPProxyAddress\0"
481 "Bridge\0"
482 "BridgeFDB\0"
483 "BridgeVLAN\0"
484 "IPv6PrefixDelegation\0"
485 "IPv6Prefix\0"
486 "IPv6RoutePrefix\0"
487 "TrafficControlQueueingDiscipline\0"
488 "CAN\0"
489 "QDisc\0"
490 "BFIFO\0"
491 "CAKE\0"
492 "ControlledDelay\0"
493 "DeficitRoundRobinScheduler\0"
494 "DeficitRoundRobinSchedulerClass\0"
495 "PFIFO\0"
496 "PFIFOFast\0"
497 "PFIFOHeadDrop\0"
498 "FairQueueing\0"
499 "FairQueueingControlledDelay\0"
500 "GenericRandomEarlyDetection\0"
501 "HeavyHitterFilter\0"
502 "HierarchyTokenBucket\0"
503 "HierarchyTokenBucketClass\0"
504 "NetworkEmulator\0"
505 "PIE\0"
506 "StochasticFairBlue\0"
507 "StochasticFairnessQueueing\0"
508 "TokenBucketFilter\0"
509 "TrivialLinkEqualizer\0",
510 config_item_perf_lookup, network_network_gperf_lookup,
511 CONFIG_PARSE_WARN, network);
512 if (r < 0)
513 return r;
514
515 network_apply_anonymize_if_set(network);
516
517 r = network_add_ipv4ll_route(network);
518 if (r < 0)
519 log_warning_errno(r, "%s: Failed to add IPv4LL route, ignoring: %m", network->filename);
520
521 r = network_add_default_route_on_device(network);
522 if (r < 0)
523 log_warning_errno(r, "%s: Failed to add default route on device, ignoring: %m",
524 network->filename);
525
526 struct stat stats;
527 if (stat(filename, &stats) < 0)
528 return -errno;
529 network->timestamp = timespec_load(&stats.st_mtim);
530
531 if (network_verify(network) < 0)
532 /* Ignore .network files that do not match the conditions. */
533 return 0;
534
535 r = ordered_hashmap_ensure_allocated(networks, &string_hash_ops);
536 if (r < 0)
537 return r;
538
539 r = ordered_hashmap_put(*networks, network->name, network);
540 if (r < 0)
541 return r;
542
543 network = NULL;
544 return 0;
545 }
546
547 int network_load(Manager *manager, OrderedHashmap **networks) {
548 _cleanup_strv_free_ char **files = NULL;
549 char **f;
550 int r;
551
552 assert(manager);
553
554 ordered_hashmap_clear_with_destructor(*networks, network_unref);
555
556 r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS);
557 if (r < 0)
558 return log_error_errno(r, "Failed to enumerate network files: %m");
559
560 STRV_FOREACH(f, files) {
561 r = network_load_one(manager, networks, *f);
562 if (r < 0)
563 log_error_errno(r, "Failed to load %s, ignoring: %m", *f);
564 }
565
566 return 0;
567 }
568
569 int network_reload(Manager *manager) {
570 OrderedHashmap *new_networks = NULL;
571 Network *n, *old;
572 Iterator i;
573 int r;
574
575 assert(manager);
576
577 r = network_load(manager, &new_networks);
578 if (r < 0)
579 goto failure;
580
581 ORDERED_HASHMAP_FOREACH(n, new_networks, i) {
582 r = network_get_by_name(manager, n->name, &old);
583 if (r < 0)
584 continue; /* The .network file is new. */
585
586 if (n->timestamp != old->timestamp)
587 continue; /* The .network file is modified. */
588
589 if (!streq(n->filename, old->filename))
590 continue;
591
592 r = ordered_hashmap_replace(new_networks, old->name, old);
593 if (r < 0)
594 goto failure;
595
596 network_ref(old);
597 network_unref(n);
598 }
599
600 ordered_hashmap_free_with_destructor(manager->networks, network_unref);
601 manager->networks = new_networks;
602
603 return 0;
604
605 failure:
606 ordered_hashmap_free_with_destructor(new_networks, network_unref);
607
608 return r;
609 }
610
611 static Network *network_free(Network *network) {
612 IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
613 RoutePrefix *route_prefix;
614 RoutingPolicyRule *rule;
615 AddressLabel *label;
616 FdbEntry *fdb_entry;
617 Neighbor *neighbor;
618 Address *address;
619 NextHop *nexthop;
620 Prefix *prefix;
621 Route *route;
622
623 if (!network)
624 return NULL;
625
626 free(network->filename);
627
628 set_free_free(network->match_mac);
629 set_free_free(network->match_permanent_mac);
630 strv_free(network->match_path);
631 strv_free(network->match_driver);
632 strv_free(network->match_type);
633 strv_free(network->match_name);
634 strv_free(network->match_property);
635 strv_free(network->match_wlan_iftype);
636 strv_free(network->match_ssid);
637 set_free_free(network->match_bssid);
638 condition_free_list(network->conditions);
639
640 free(network->description);
641 free(network->dhcp_vendor_class_identifier);
642 strv_free(network->dhcp_user_class);
643 free(network->dhcp_hostname);
644 set_free(network->dhcp_black_listed_ip);
645 set_free(network->dhcp_request_options);
646 free(network->mac);
647
648 if (network->dhcp_acd)
649 sd_ipv4acd_unref(network->dhcp_acd);
650
651 strv_free(network->ntp);
652 free(network->dns);
653 strv_free(network->sip);
654 ordered_set_free_free(network->search_domains);
655 ordered_set_free_free(network->route_domains);
656 strv_free(network->bind_carrier);
657
658 ordered_set_free_free(network->router_search_domains);
659 free(network->router_dns);
660 set_free_free(network->ndisc_black_listed_prefix);
661
662 free(network->bridge_name);
663 free(network->bond_name);
664 free(network->vrf_name);
665 hashmap_free_free_key(network->stacked_netdev_names);
666 netdev_unref(network->bridge);
667 netdev_unref(network->bond);
668 netdev_unref(network->vrf);
669 hashmap_free_with_destructor(network->stacked_netdevs, netdev_unref);
670
671 while ((route = network->static_routes))
672 route_free(route);
673
674 while ((nexthop = network->static_nexthops))
675 nexthop_free(nexthop);
676
677 while ((address = network->static_addresses))
678 address_free(address);
679
680 while ((fdb_entry = network->static_fdb_entries))
681 fdb_entry_free(fdb_entry);
682
683 while ((ipv6_proxy_ndp_address = network->ipv6_proxy_ndp_addresses))
684 ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address);
685
686 while ((neighbor = network->neighbors))
687 neighbor_free(neighbor);
688
689 while ((label = network->address_labels))
690 address_label_free(label);
691
692 while ((prefix = network->static_prefixes))
693 prefix_free(prefix);
694
695 while ((route_prefix = network->static_route_prefixes))
696 route_prefix_free(route_prefix);
697
698 while ((rule = network->rules))
699 routing_policy_rule_free(rule);
700
701 hashmap_free(network->addresses_by_section);
702 hashmap_free(network->routes_by_section);
703 hashmap_free(network->nexthops_by_section);
704 hashmap_free(network->fdb_entries_by_section);
705 hashmap_free(network->neighbors_by_section);
706 hashmap_free(network->address_labels_by_section);
707 hashmap_free(network->prefixes_by_section);
708 hashmap_free(network->route_prefixes_by_section);
709 hashmap_free(network->rules_by_section);
710 ordered_hashmap_free_with_destructor(network->tc_by_section, traffic_control_free);
711
712 if (network->manager &&
713 network->manager->duids_requesting_uuid)
714 set_remove(network->manager->duids_requesting_uuid, &network->duid);
715
716 free(network->name);
717
718 free(network->dhcp_server_timezone);
719 free(network->dhcp_server_dns);
720 free(network->dhcp_server_ntp);
721 free(network->dhcp_server_sip);
722
723 set_free_free(network->dnssec_negative_trust_anchors);
724
725 ordered_hashmap_free(network->dhcp_client_send_options);
726 ordered_hashmap_free(network->dhcp_client_send_vendor_options);
727 ordered_hashmap_free(network->dhcp_server_send_options);
728 ordered_hashmap_free(network->dhcp_server_send_vendor_options);
729 ordered_hashmap_free(network->ipv6_tokens);
730
731 return mfree(network);
732 }
733
734 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network, network, network_free);
735
736 int network_get_by_name(Manager *manager, const char *name, Network **ret) {
737 Network *network;
738
739 assert(manager);
740 assert(name);
741 assert(ret);
742
743 network = ordered_hashmap_get(manager->networks, name);
744 if (!network)
745 return -ENOENT;
746
747 *ret = network;
748
749 return 0;
750 }
751
752 int network_get(Manager *manager, unsigned short iftype, sd_device *device,
753 const char *ifname, char * const *alternative_names,
754 const struct ether_addr *address, const struct ether_addr *permanent_address,
755 enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid,
756 Network **ret) {
757 Network *network;
758 Iterator i;
759
760 assert(manager);
761 assert(ret);
762
763 ORDERED_HASHMAP_FOREACH(network, manager->networks, i)
764 if (net_match_config(network->match_mac, network->match_permanent_mac,
765 network->match_path, network->match_driver,
766 network->match_type, network->match_name, network->match_property,
767 network->match_wlan_iftype, network->match_ssid, network->match_bssid,
768 iftype, device, address, permanent_address,
769 ifname, alternative_names, wlan_iftype, ssid, bssid)) {
770 if (network->match_name && device) {
771 const char *attr;
772 uint8_t name_assign_type = NET_NAME_UNKNOWN;
773
774 if (sd_device_get_sysattr_value(device, "name_assign_type", &attr) >= 0)
775 (void) safe_atou8(attr, &name_assign_type);
776
777 if (name_assign_type == NET_NAME_ENUM)
778 log_warning("%s: found matching network '%s', based on potentially unpredictable ifname",
779 ifname, network->filename);
780 else
781 log_debug("%s: found matching network '%s'", ifname, network->filename);
782 } else
783 log_debug("%s: found matching network '%s'", ifname, network->filename);
784
785 *ret = network;
786 return 0;
787 }
788
789 *ret = NULL;
790
791 return -ENOENT;
792 }
793
794 int network_apply(Network *network, Link *link) {
795 assert(network);
796 assert(link);
797
798 link->network = network_ref(network);
799
800 if (network->n_dns > 0 ||
801 !strv_isempty(network->ntp) ||
802 !ordered_set_isempty(network->search_domains) ||
803 !ordered_set_isempty(network->route_domains))
804 link_dirty(link);
805
806 return 0;
807 }
808
809 bool network_has_static_ipv6_configurations(Network *network) {
810 Address *address;
811 Route *route;
812 FdbEntry *fdb;
813 Neighbor *neighbor;
814
815 assert(network);
816
817 LIST_FOREACH(addresses, address, network->static_addresses)
818 if (address->family == AF_INET6)
819 return true;
820
821 LIST_FOREACH(routes, route, network->static_routes)
822 if (route->family == AF_INET6)
823 return true;
824
825 LIST_FOREACH(static_fdb_entries, fdb, network->static_fdb_entries)
826 if (fdb->family == AF_INET6)
827 return true;
828
829 LIST_FOREACH(neighbors, neighbor, network->neighbors)
830 if (neighbor->family == AF_INET6)
831 return true;
832
833 if (!LIST_IS_EMPTY(network->address_labels))
834 return true;
835
836 if (!LIST_IS_EMPTY(network->static_prefixes))
837 return true;
838
839 return false;
840 }
841
842 int config_parse_stacked_netdev(const char *unit,
843 const char *filename,
844 unsigned line,
845 const char *section,
846 unsigned section_line,
847 const char *lvalue,
848 int ltype,
849 const char *rvalue,
850 void *data,
851 void *userdata) {
852 _cleanup_free_ char *name = NULL;
853 NetDevKind kind = ltype;
854 Hashmap **h = data;
855 int r;
856
857 assert(filename);
858 assert(lvalue);
859 assert(rvalue);
860 assert(data);
861 assert(IN_SET(kind,
862 NETDEV_KIND_VLAN, NETDEV_KIND_MACVLAN, NETDEV_KIND_MACVTAP,
863 NETDEV_KIND_IPVLAN, NETDEV_KIND_IPVTAP, NETDEV_KIND_VXLAN,
864 NETDEV_KIND_L2TP, NETDEV_KIND_MACSEC, _NETDEV_KIND_TUNNEL,
865 NETDEV_KIND_XFRM));
866
867 if (!ifname_valid(rvalue)) {
868 log_syntax(unit, LOG_ERR, filename, line, 0,
869 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue, rvalue);
870 return 0;
871 }
872
873 name = strdup(rvalue);
874 if (!name)
875 return log_oom();
876
877 r = hashmap_ensure_allocated(h, &string_hash_ops);
878 if (r < 0)
879 return log_oom();
880
881 r = hashmap_put(*h, name, INT_TO_PTR(kind));
882 if (r < 0)
883 log_syntax(unit, LOG_ERR, filename, line, r,
884 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name);
885 else if (r == 0)
886 log_syntax(unit, LOG_DEBUG, filename, line, r,
887 "NetDev '%s' specified twice, ignoring.", name);
888 else
889 name = NULL;
890
891 return 0;
892 }
893
894 int config_parse_domains(
895 const char *unit,
896 const char *filename,
897 unsigned line,
898 const char *section,
899 unsigned section_line,
900 const char *lvalue,
901 int ltype,
902 const char *rvalue,
903 void *data,
904 void *userdata) {
905
906 const char *p;
907 Network *n = data;
908 int r;
909
910 assert(n);
911 assert(lvalue);
912 assert(rvalue);
913
914 if (isempty(rvalue)) {
915 n->search_domains = ordered_set_free_free(n->search_domains);
916 n->route_domains = ordered_set_free_free(n->route_domains);
917 return 0;
918 }
919
920 p = rvalue;
921 for (;;) {
922 _cleanup_free_ char *w = NULL, *normalized = NULL;
923 const char *domain;
924 bool is_route;
925
926 r = extract_first_word(&p, &w, NULL, 0);
927 if (r < 0) {
928 log_syntax(unit, LOG_ERR, filename, line, r,
929 "Failed to extract search or route domain, ignoring: %s", rvalue);
930 break;
931 }
932 if (r == 0)
933 break;
934
935 is_route = w[0] == '~';
936 domain = is_route ? w + 1 : w;
937
938 if (dns_name_is_root(domain) || streq(domain, "*")) {
939 /* If the root domain appears as is, or the special token "*" is found, we'll
940 * consider this as routing domain, unconditionally. */
941 is_route = true;
942 domain = "."; /* make sure we don't allow empty strings, thus write the root
943 * domain as "." */
944 } else {
945 r = dns_name_normalize(domain, 0, &normalized);
946 if (r < 0) {
947 log_syntax(unit, LOG_ERR, filename, line, r,
948 "'%s' is not a valid domain name, ignoring.", domain);
949 continue;
950 }
951
952 domain = normalized;
953
954 if (is_localhost(domain)) {
955 log_syntax(unit, LOG_ERR, filename, line, 0,
956 "'localhost' domain may not be configured as search or route domain, ignoring assignment: %s",
957 domain);
958 continue;
959 }
960 }
961
962 OrderedSet **set = is_route ? &n->route_domains : &n->search_domains;
963 r = ordered_set_ensure_allocated(set, &string_hash_ops);
964 if (r < 0)
965 return r;
966
967 r = ordered_set_put_strdup(*set, domain);
968 if (r < 0)
969 return log_oom();
970 }
971
972 return 0;
973 }
974
975 int config_parse_ipv6token(
976 const char* unit,
977 const char *filename,
978 unsigned line,
979 const char *section,
980 unsigned section_line,
981 const char *lvalue,
982 int ltype,
983 const char *rvalue,
984 void *data,
985 void *userdata) {
986
987 union in_addr_union buffer;
988 struct in6_addr *token = data;
989 int r;
990
991 assert(filename);
992 assert(lvalue);
993 assert(rvalue);
994 assert(token);
995
996 r = in_addr_from_string(AF_INET6, rvalue, &buffer);
997 if (r < 0) {
998 log_syntax(unit, LOG_ERR, filename, line, r,
999 "Failed to parse IPv6 token, ignoring: %s", rvalue);
1000 return 0;
1001 }
1002
1003 if (in_addr_is_null(AF_INET6, &buffer)) {
1004 log_syntax(unit, LOG_ERR, filename, line, 0,
1005 "IPv6 token cannot be the ANY address, ignoring: %s", rvalue);
1006 return 0;
1007 }
1008
1009 if ((buffer.in6.s6_addr32[0] | buffer.in6.s6_addr32[1]) != 0) {
1010 log_syntax(unit, LOG_ERR, filename, line, 0,
1011 "IPv6 token cannot be longer than 64 bits, ignoring: %s", rvalue);
1012 return 0;
1013 }
1014
1015 *token = buffer.in6;
1016
1017 return 0;
1018 }
1019
1020 static const char* const ipv6_privacy_extensions_table[_IPV6_PRIVACY_EXTENSIONS_MAX] = {
1021 [IPV6_PRIVACY_EXTENSIONS_NO] = "no",
1022 [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC] = "prefer-public",
1023 [IPV6_PRIVACY_EXTENSIONS_YES] = "yes",
1024 };
1025
1026 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(ipv6_privacy_extensions, IPv6PrivacyExtensions,
1027 IPV6_PRIVACY_EXTENSIONS_YES);
1028
1029 int config_parse_ipv6_privacy_extensions(
1030 const char* unit,
1031 const char *filename,
1032 unsigned line,
1033 const char *section,
1034 unsigned section_line,
1035 const char *lvalue,
1036 int ltype,
1037 const char *rvalue,
1038 void *data,
1039 void *userdata) {
1040
1041 IPv6PrivacyExtensions s, *ipv6_privacy_extensions = data;
1042
1043 assert(filename);
1044 assert(lvalue);
1045 assert(rvalue);
1046 assert(ipv6_privacy_extensions);
1047
1048 s = ipv6_privacy_extensions_from_string(rvalue);
1049 if (s < 0) {
1050 if (streq(rvalue, "kernel"))
1051 s = _IPV6_PRIVACY_EXTENSIONS_INVALID;
1052 else {
1053 log_syntax(unit, LOG_ERR, filename, line, 0,
1054 "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue);
1055 return 0;
1056 }
1057 }
1058
1059 *ipv6_privacy_extensions = s;
1060
1061 return 0;
1062 }
1063
1064 int config_parse_hostname(
1065 const char *unit,
1066 const char *filename,
1067 unsigned line,
1068 const char *section,
1069 unsigned section_line,
1070 const char *lvalue,
1071 int ltype,
1072 const char *rvalue,
1073 void *data,
1074 void *userdata) {
1075
1076 _cleanup_free_ char *hn = NULL;
1077 char **hostname = data;
1078 int r;
1079
1080 assert(filename);
1081 assert(lvalue);
1082 assert(rvalue);
1083
1084 r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &hn, userdata);
1085 if (r < 0)
1086 return r;
1087
1088 if (!hostname_is_valid(hn, false)) {
1089 log_syntax(unit, LOG_ERR, filename, line, 0,
1090 "Hostname is not valid, ignoring assignment: %s", rvalue);
1091 return 0;
1092 }
1093
1094 r = dns_name_is_valid(hn);
1095 if (r < 0) {
1096 log_syntax(unit, LOG_ERR, filename, line, r,
1097 "Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue);
1098 return 0;
1099 }
1100 if (r == 0) {
1101 log_syntax(unit, LOG_ERR, filename, line, 0,
1102 "Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue);
1103 return 0;
1104 }
1105
1106 return free_and_replace(*hostname, hn);
1107 }
1108
1109 int config_parse_timezone(
1110 const char *unit,
1111 const char *filename,
1112 unsigned line,
1113 const char *section,
1114 unsigned section_line,
1115 const char *lvalue,
1116 int ltype,
1117 const char *rvalue,
1118 void *data,
1119 void *userdata) {
1120
1121 _cleanup_free_ char *tz = NULL;
1122 char **datap = data;
1123 int r;
1124
1125 assert(filename);
1126 assert(lvalue);
1127 assert(rvalue);
1128
1129 r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &tz, userdata);
1130 if (r < 0)
1131 return r;
1132
1133 if (!timezone_is_valid(tz, LOG_ERR)) {
1134 log_syntax(unit, LOG_ERR, filename, line, 0,
1135 "Timezone is not valid, ignoring assignment: %s", rvalue);
1136 return 0;
1137 }
1138
1139 return free_and_replace(*datap, tz);
1140 }
1141
1142 int config_parse_dns(
1143 const char *unit,
1144 const char *filename,
1145 unsigned line,
1146 const char *section,
1147 unsigned section_line,
1148 const char *lvalue,
1149 int ltype,
1150 const char *rvalue,
1151 void *data,
1152 void *userdata) {
1153
1154 Network *n = userdata;
1155 int r;
1156
1157 assert(filename);
1158 assert(lvalue);
1159 assert(rvalue);
1160
1161 for (;;) {
1162 _cleanup_free_ char *w = NULL;
1163 union in_addr_union a;
1164 struct in_addr_data *m;
1165 int family;
1166
1167 r = extract_first_word(&rvalue, &w, NULL, 0);
1168 if (r == -ENOMEM)
1169 return log_oom();
1170 if (r < 0) {
1171 log_syntax(unit, LOG_ERR, filename, line, r,
1172 "Invalid syntax, ignoring: %s", rvalue);
1173 break;
1174 }
1175 if (r == 0)
1176 break;
1177
1178 r = in_addr_from_string_auto(w, &family, &a);
1179 if (r < 0) {
1180 log_syntax(unit, LOG_ERR, filename, line, r,
1181 "Failed to parse dns server address, ignoring: %s", w);
1182 continue;
1183 }
1184
1185 m = reallocarray(n->dns, n->n_dns + 1, sizeof(struct in_addr_data));
1186 if (!m)
1187 return log_oom();
1188
1189 m[n->n_dns++] = (struct in_addr_data) {
1190 .family = family,
1191 .address = a,
1192 };
1193
1194 n->dns = m;
1195 }
1196
1197 return 0;
1198 }
1199
1200 int config_parse_dnssec_negative_trust_anchors(
1201 const char *unit,
1202 const char *filename,
1203 unsigned line,
1204 const char *section,
1205 unsigned section_line,
1206 const char *lvalue,
1207 int ltype,
1208 const char *rvalue,
1209 void *data,
1210 void *userdata) {
1211
1212 const char *p = rvalue;
1213 Network *n = data;
1214 int r;
1215
1216 assert(n);
1217 assert(lvalue);
1218 assert(rvalue);
1219
1220 if (isempty(rvalue)) {
1221 n->dnssec_negative_trust_anchors = set_free_free(n->dnssec_negative_trust_anchors);
1222 return 0;
1223 }
1224
1225 for (;;) {
1226 _cleanup_free_ char *w = NULL;
1227
1228 r = extract_first_word(&p, &w, NULL, 0);
1229 if (r < 0) {
1230 log_syntax(unit, LOG_ERR, filename, line, r,
1231 "Failed to extract negative trust anchor domain, ignoring: %s", rvalue);
1232 break;
1233 }
1234 if (r == 0)
1235 break;
1236
1237 r = dns_name_is_valid(w);
1238 if (r <= 0) {
1239 log_syntax(unit, LOG_ERR, filename, line, r,
1240 "%s is not a valid domain name, ignoring.", w);
1241 continue;
1242 }
1243
1244 r = set_ensure_allocated(&n->dnssec_negative_trust_anchors, &dns_name_hash_ops);
1245 if (r < 0)
1246 return log_oom();
1247
1248 r = set_put(n->dnssec_negative_trust_anchors, w);
1249 if (r < 0)
1250 return log_oom();
1251 if (r > 0)
1252 w = NULL;
1253 }
1254
1255 return 0;
1256 }
1257
1258 int config_parse_ntp(
1259 const char *unit,
1260 const char *filename,
1261 unsigned line,
1262 const char *section,
1263 unsigned section_line,
1264 const char *lvalue,
1265 int ltype,
1266 const char *rvalue,
1267 void *data,
1268 void *userdata) {
1269
1270 char ***l = data;
1271 int r;
1272
1273 assert(l);
1274 assert(lvalue);
1275 assert(rvalue);
1276
1277 if (isempty(rvalue)) {
1278 *l = strv_free(*l);
1279 return 0;
1280 }
1281
1282 for (;;) {
1283 _cleanup_free_ char *w = NULL;
1284
1285 r = extract_first_word(&rvalue, &w, NULL, 0);
1286 if (r == -ENOMEM)
1287 return log_oom();
1288 if (r < 0) {
1289 log_syntax(unit, LOG_ERR, filename, line, r,
1290 "Failed to extract NTP server name, ignoring: %s", rvalue);
1291 break;
1292 }
1293 if (r == 0)
1294 break;
1295
1296 r = dns_name_is_valid_or_address(w);
1297 if (r <= 0) {
1298 log_syntax(unit, LOG_ERR, filename, line, r,
1299 "%s is not a valid domain name or IP address, ignoring.", w);
1300 continue;
1301 }
1302
1303 if (strv_length(*l) > MAX_NTP_SERVERS) {
1304 log_syntax(unit, LOG_WARNING, filename, line, 0,
1305 "More than %u NTP servers specified, ignoring \"%s\" and any subsequent entries.",
1306 MAX_NTP_SERVERS, w);
1307 break;
1308 }
1309
1310 r = strv_consume(l, TAKE_PTR(w));
1311 if (r < 0)
1312 return log_oom();
1313 }
1314
1315 return 0;
1316 }
1317
1318 int config_parse_required_for_online(
1319 const char *unit,
1320 const char *filename,
1321 unsigned line,
1322 const char *section,
1323 unsigned section_line,
1324 const char *lvalue,
1325 int ltype,
1326 const char *rvalue,
1327 void *data,
1328 void *userdata) {
1329
1330 Network *network = data;
1331 LinkOperationalStateRange range;
1332 bool required = true;
1333 int r;
1334
1335 if (isempty(rvalue)) {
1336 network->required_for_online = true;
1337 network->required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT;
1338 return 0;
1339 }
1340
1341 r = parse_operational_state_range(rvalue, &range);
1342 if (r < 0) {
1343 r = parse_boolean(rvalue);
1344 if (r < 0) {
1345 log_syntax(unit, LOG_ERR, filename, line, r,
1346 "Failed to parse %s= setting, ignoring assignment: %s",
1347 lvalue, rvalue);
1348 return 0;
1349 }
1350
1351 required = r;
1352 range = LINK_OPERSTATE_RANGE_DEFAULT;
1353 }
1354
1355 network->required_for_online = required;
1356 network->required_operstate_for_online = range;
1357
1358 return 0;
1359 }
1360
1361 DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration, keep_configuration, KeepConfiguration,
1362 "Failed to parse KeepConfiguration= setting");
1363
1364 static const char* const keep_configuration_table[_KEEP_CONFIGURATION_MAX] = {
1365 [KEEP_CONFIGURATION_NO] = "no",
1366 [KEEP_CONFIGURATION_DHCP_ON_STOP] = "dhcp-on-stop",
1367 [KEEP_CONFIGURATION_DHCP] = "dhcp",
1368 [KEEP_CONFIGURATION_STATIC] = "static",
1369 [KEEP_CONFIGURATION_YES] = "yes",
1370 };
1371
1372 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration, KeepConfiguration, KEEP_CONFIGURATION_YES);