]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/networkd-network.c
man/systemd-sysext: list ephemeral/ephemeral-import in the list of options
[thirdparty/systemd.git] / src / network / networkd-network.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <unistd.h>
4
5 #include "alloc-util.h"
6 #include "condition.h"
7 #include "conf-files.h"
8 #include "conf-parser.h"
9 #include "in-addr-util.h"
10 #include "net-condition.h"
11 #include "netdev/macvlan.h"
12 #include "netif-sriov.h"
13 #include "network-util.h"
14 #include "networkd-address.h"
15 #include "networkd-address-label.h"
16 #include "networkd-bridge-fdb.h"
17 #include "networkd-bridge-mdb.h"
18 #include "networkd-dhcp-common.h"
19 #include "networkd-dhcp-server-static-lease.h"
20 #include "networkd-ipv6-proxy-ndp.h"
21 #include "networkd-manager.h"
22 #include "networkd-ndisc.h"
23 #include "networkd-neighbor.h"
24 #include "networkd-network.h"
25 #include "networkd-nexthop.h"
26 #include "networkd-radv.h"
27 #include "networkd-route.h"
28 #include "networkd-routing-policy-rule.h"
29 #include "ordered-set.h"
30 #include "parse-util.h"
31 #include "path-util.h"
32 #include "qdisc.h"
33 #include "radv-internal.h"
34 #include "set.h"
35 #include "socket-util.h"
36 #include "stat-util.h"
37 #include "string-table.h"
38 #include "string-util.h"
39 #include "strv.h"
40 #include "tclass.h"
41
42 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
43 network_hash_ops,
44 char, string_hash_func, string_compare_func,
45 Network, network_unref);
46
47 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
48 stacked_netdevs_hash_ops,
49 char, string_hash_func, string_compare_func,
50 NetDev, netdev_unref);
51
52 static int network_resolve_netdev_one(Network *network, const char *name, NetDevKind kind, NetDev **ret) {
53 const char *kind_string;
54 NetDev *netdev;
55 int r;
56
57 /* For test-networkd-conf, the check must be earlier than the assertions. */
58 if (!name)
59 return 0;
60
61 assert(network);
62 assert(network->manager);
63 assert(network->filename);
64 assert(ret);
65
66 if (kind == _NETDEV_KIND_TUNNEL)
67 kind_string = "tunnel";
68 else {
69 kind_string = netdev_kind_to_string(kind);
70 if (!kind_string)
71 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
72 "%s: Invalid NetDev kind of %s, ignoring assignment.",
73 network->filename, name);
74 }
75
76 r = netdev_get(network->manager, name, &netdev);
77 if (r < 0)
78 return log_warning_errno(r, "%s: %s NetDev could not be found, ignoring assignment.",
79 network->filename, name);
80
81 if (netdev->kind != kind && !(kind == _NETDEV_KIND_TUNNEL &&
82 IN_SET(netdev->kind,
83 NETDEV_KIND_ERSPAN,
84 NETDEV_KIND_GRE,
85 NETDEV_KIND_GRETAP,
86 NETDEV_KIND_IP6GRE,
87 NETDEV_KIND_IP6GRETAP,
88 NETDEV_KIND_IP6TNL,
89 NETDEV_KIND_IPIP,
90 NETDEV_KIND_SIT,
91 NETDEV_KIND_VTI,
92 NETDEV_KIND_VTI6)))
93 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
94 "%s: NetDev %s is not a %s, ignoring assignment",
95 network->filename, name, kind_string);
96
97 *ret = netdev_ref(netdev);
98 return 1;
99 }
100
101 static int network_resolve_stacked_netdevs(Network *network) {
102 void *name, *kind;
103 int r;
104
105 assert(network);
106
107 HASHMAP_FOREACH_KEY(kind, name, network->stacked_netdev_names) {
108 _cleanup_(netdev_unrefp) NetDev *netdev = NULL;
109
110 if (network_resolve_netdev_one(network, name, PTR_TO_INT(kind), &netdev) <= 0)
111 continue;
112
113 r = hashmap_ensure_put(&network->stacked_netdevs, &stacked_netdevs_hash_ops, netdev->ifname, netdev);
114 if (r == -ENOMEM)
115 return log_oom();
116 if (r < 0)
117 log_warning_errno(r, "%s: Failed to add NetDev '%s' to network, ignoring: %m",
118 network->filename, (const char *) name);
119
120 TAKE_PTR(netdev);
121 }
122
123 return 0;
124 }
125
126 int network_verify(Network *network) {
127 int r;
128
129 assert(network);
130 assert(network->manager);
131 assert(network->filename);
132
133 if (net_match_is_empty(&network->match) && !network->conditions)
134 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
135 "%s: No valid settings found in the [Match] section, ignoring file. "
136 "To match all interfaces, add Name=* in the [Match] section.",
137 network->filename);
138
139 /* skip out early if configuration does not match the environment */
140 if (!condition_test_list(network->conditions, environ, NULL, NULL, NULL))
141 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
142 "%s: Conditions in the file do not match the system environment, skipping.",
143 network->filename);
144
145 if (network->keep_master) {
146 if (network->batadv_name)
147 log_warning("%s: BatmanAdvanced= set with KeepMaster= enabled, ignoring BatmanAdvanced=.",
148 network->filename);
149 if (network->bond_name)
150 log_warning("%s: Bond= set with KeepMaster= enabled, ignoring Bond=.",
151 network->filename);
152 if (network->bridge_name)
153 log_warning("%s: Bridge= set with KeepMaster= enabled, ignoring Bridge=.",
154 network->filename);
155 if (network->vrf_name)
156 log_warning("%s: VRF= set with KeepMaster= enabled, ignoring VRF=.",
157 network->filename);
158
159 network->batadv_name = mfree(network->batadv_name);
160 network->bond_name = mfree(network->bond_name);
161 network->bridge_name = mfree(network->bridge_name);
162 network->vrf_name = mfree(network->vrf_name);
163 }
164
165 (void) network_resolve_netdev_one(network, network->batadv_name, NETDEV_KIND_BATADV, &network->batadv);
166 (void) network_resolve_netdev_one(network, network->bond_name, NETDEV_KIND_BOND, &network->bond);
167 (void) network_resolve_netdev_one(network, network->bridge_name, NETDEV_KIND_BRIDGE, &network->bridge);
168 (void) network_resolve_netdev_one(network, network->vrf_name, NETDEV_KIND_VRF, &network->vrf);
169 r = network_resolve_stacked_netdevs(network);
170 if (r < 0)
171 return r;
172
173 /* Free unnecessary entries. */
174 network->batadv_name = mfree(network->batadv_name);
175 network->bond_name = mfree(network->bond_name);
176 network->bridge_name = mfree(network->bridge_name);
177 network->vrf_name = mfree(network->vrf_name);
178 network->stacked_netdev_names = hashmap_free(network->stacked_netdev_names);
179
180 if (network->bond) {
181 /* Bonding slave does not support addressing. */
182 if (network->link_local >= 0 && network->link_local != ADDRESS_FAMILY_NO) {
183 log_warning("%s: Cannot enable LinkLocalAddressing= when Bond= is specified, disabling LinkLocalAddressing=.",
184 network->filename);
185 network->link_local = ADDRESS_FAMILY_NO;
186 }
187 if (!ordered_hashmap_isempty(network->addresses_by_section))
188 log_warning("%s: Cannot set addresses when Bond= is specified, ignoring addresses.",
189 network->filename);
190 if (!hashmap_isempty(network->routes_by_section))
191 log_warning("%s: Cannot set routes when Bond= is specified, ignoring routes.",
192 network->filename);
193
194 network->addresses_by_section = ordered_hashmap_free(network->addresses_by_section);
195 network->routes_by_section = hashmap_free(network->routes_by_section);
196 }
197
198 if (network->link_local < 0) {
199 network->link_local = ADDRESS_FAMILY_IPV6;
200
201 if (network->keep_master || network->bridge)
202 network->link_local = ADDRESS_FAMILY_NO;
203 else {
204 NetDev *netdev;
205
206 HASHMAP_FOREACH(netdev, network->stacked_netdevs) {
207 MacVlan *m;
208
209 if (netdev->kind == NETDEV_KIND_MACVLAN)
210 m = MACVLAN(netdev);
211 else if (netdev->kind == NETDEV_KIND_MACVTAP)
212 m = MACVTAP(netdev);
213 else
214 continue;
215
216 if (m->mode == NETDEV_MACVLAN_MODE_PASSTHRU)
217 network->link_local = ADDRESS_FAMILY_NO;
218
219 /* There won't be a passthru MACVLAN/MACVTAP if there's already one in another mode */
220 break;
221 }
222 }
223 }
224
225 if (network->ipv6ll_address_gen_mode == IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_NONE)
226 SET_FLAG(network->link_local, ADDRESS_FAMILY_IPV6, false);
227
228 if (in6_addr_is_set(&network->ipv6ll_stable_secret) &&
229 network->ipv6ll_address_gen_mode < 0)
230 network->ipv6ll_address_gen_mode = IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY;
231
232 network_adjust_ipv6_proxy_ndp(network);
233 network_adjust_ndisc(network);
234 network_adjust_dhcp(network);
235 network_adjust_radv(network);
236 network_adjust_bridge_vlan(network);
237
238 if (network->mtu > 0 && network->dhcp_use_mtu) {
239 log_warning("%s: MTUBytes= in [Link] section and UseMTU= in [DHCP] section are set. "
240 "Disabling UseMTU=.", network->filename);
241 network->dhcp_use_mtu = false;
242 }
243
244 if (network->dhcp_critical >= 0) {
245 if (network->keep_configuration >= 0) {
246 if (network->manager->keep_configuration < 0)
247 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
248 "Ignoring CriticalConnection=.", network->filename);
249 } else if (network->dhcp_critical)
250 /* CriticalConnection=yes also preserve foreign static configurations. */
251 network->keep_configuration = KEEP_CONFIGURATION_YES;
252 else
253 network->keep_configuration = KEEP_CONFIGURATION_NO;
254 }
255
256 if (!strv_isempty(network->bind_carrier)) {
257 if (!IN_SET(network->activation_policy, _ACTIVATION_POLICY_INVALID, ACTIVATION_POLICY_BOUND))
258 log_warning("%s: ActivationPolicy=bound is required with BindCarrier=. "
259 "Setting ActivationPolicy=bound.", network->filename);
260 network->activation_policy = ACTIVATION_POLICY_BOUND;
261 } else if (network->activation_policy == ACTIVATION_POLICY_BOUND) {
262 log_warning("%s: ActivationPolicy=bound requires BindCarrier=. "
263 "Ignoring ActivationPolicy=bound.", network->filename);
264 network->activation_policy = ACTIVATION_POLICY_UP;
265 }
266
267 if (network->activation_policy == _ACTIVATION_POLICY_INVALID)
268 network->activation_policy = ACTIVATION_POLICY_UP;
269
270 if (network->activation_policy == ACTIVATION_POLICY_ALWAYS_UP) {
271 if (network->ignore_carrier_loss_set && network->ignore_carrier_loss_usec < USEC_INFINITY)
272 log_warning("%s: IgnoreCarrierLoss=no or finite timespan conflicts with ActivationPolicy=always-up. "
273 "Setting IgnoreCarrierLoss=yes.", network->filename);
274 network->ignore_carrier_loss_set = true;
275 network->ignore_carrier_loss_usec = USEC_INFINITY;
276 }
277
278 if (!network->ignore_carrier_loss_set) /* Set implied default. */
279 network->ignore_carrier_loss_usec = network->configure_without_carrier ? USEC_INFINITY : 0;
280
281 if (IN_SET(network->activation_policy, ACTIVATION_POLICY_DOWN, ACTIVATION_POLICY_ALWAYS_DOWN, ACTIVATION_POLICY_MANUAL)) {
282 if (network->required_for_online < 0 ||
283 (network->required_for_online == true && network->activation_policy == ACTIVATION_POLICY_ALWAYS_DOWN)) {
284 log_debug("%s: Setting RequiredForOnline=no because ActivationPolicy=%s.", network->filename,
285 activation_policy_to_string(network->activation_policy));
286 network->required_for_online = false;
287 } else if (network->required_for_online == true)
288 log_warning("%s: RequiredForOnline=yes and ActivationPolicy=%s, "
289 "this may cause a delay at boot.", network->filename,
290 activation_policy_to_string(network->activation_policy));
291 }
292
293 if (network->required_for_online < 0)
294 network->required_for_online = true;
295
296 if (network->keep_configuration < 0)
297 network->keep_configuration = KEEP_CONFIGURATION_NO;
298
299 r = network_drop_invalid_addresses(network);
300 if (r < 0)
301 return r; /* network_drop_invalid_addresses() logs internally. */
302 network_drop_invalid_routes(network);
303 r = network_drop_invalid_nexthops(network);
304 if (r < 0)
305 return r;
306 network_drop_invalid_bridge_fdb_entries(network);
307 network_drop_invalid_bridge_mdb_entries(network);
308 r = network_drop_invalid_neighbors(network);
309 if (r < 0)
310 return r;
311 network_drop_invalid_address_labels(network);
312 network_drop_invalid_routing_policy_rules(network);
313 network_drop_invalid_qdisc(network);
314 network_drop_invalid_tclass(network);
315 r = sr_iov_drop_invalid_sections(UINT32_MAX, network->sr_iov_by_section);
316 if (r < 0)
317 return r; /* sr_iov_drop_invalid_sections() logs internally. */
318 network_drop_invalid_static_leases(network);
319
320 return 0;
321 }
322
323 int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename) {
324 _cleanup_free_ char *fname = NULL, *name = NULL;
325 _cleanup_(network_unrefp) Network *network = NULL;
326 const char *dropin_dirname;
327 char *d;
328 int r;
329
330 assert(manager);
331 assert(filename);
332
333 r = null_or_empty_path(filename);
334 if (r < 0)
335 return log_warning_errno(r, "Failed to check if \"%s\" is empty: %m", filename);
336 if (r > 0) {
337 log_debug("Skipping empty file: %s", filename);
338 return 0;
339 }
340
341 fname = strdup(filename);
342 if (!fname)
343 return log_oom();
344
345 r = path_extract_filename(filename, &name);
346 if (r < 0)
347 return log_warning_errno(r, "Failed to extract file name of \"%s\": %m", filename);
348
349 d = strrchr(name, '.');
350 if (!d)
351 return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid file name: %s", filename);
352
353 *d = '\0';
354
355 dropin_dirname = strjoina(name, ".network.d");
356
357 network = new(Network, 1);
358 if (!network)
359 return log_oom();
360
361 *network = (Network) {
362 .filename = TAKE_PTR(fname),
363 .name = TAKE_PTR(name),
364
365 .manager = manager,
366 .n_ref = 1,
367
368 .required_for_online = -1,
369 .required_operstate_for_online = LINK_OPERSTATE_RANGE_INVALID,
370 .activation_policy = _ACTIVATION_POLICY_INVALID,
371 .group = -1,
372 .arp = -1,
373 .multicast = -1,
374 .allmulticast = -1,
375 .promiscuous = -1,
376
377 .keep_configuration = manager->keep_configuration,
378
379 .use_domains = _USE_DOMAINS_INVALID,
380
381 .compat_dhcp_use_domains = _USE_DOMAINS_INVALID,
382 .compat_dhcp_use_dns = -1,
383 .compat_dhcp_use_ntp = -1,
384
385 .dhcp_duid.type = _DUID_TYPE_INVALID,
386 .dhcp_critical = -1,
387 .dhcp_use_ntp = -1,
388 .dhcp_routes_to_ntp = true,
389 .dhcp_use_sip = true,
390 .dhcp_use_captive_portal = true,
391 .dhcp_use_dns = -1,
392 .dhcp_use_dnr = -1,
393 .dhcp_routes_to_dns = true,
394 .dhcp_use_domains = _USE_DOMAINS_INVALID,
395 .dhcp_use_hostname = true,
396 .dhcp_use_routes = true,
397 .dhcp_use_gateway = -1,
398 .dhcp_send_hostname = true,
399 .dhcp_send_release = true,
400 .dhcp_route_metric = DHCP_ROUTE_METRIC,
401 .dhcp_use_rapid_commit = -1,
402 .dhcp_client_identifier = _DHCP_CLIENT_ID_INVALID,
403 .dhcp_route_table = RT_TABLE_MAIN,
404 .dhcp_ip_service_type = -1,
405 .dhcp_broadcast = -1,
406 .dhcp_ipv6_only_mode = -1,
407 .dhcp_6rd_prefix_route_type = RTN_UNREACHABLE,
408
409 .dhcp6_use_address = true,
410 .dhcp6_use_pd_prefix = true,
411 .dhcp6_use_dns = -1,
412 .dhcp6_use_dnr = -1,
413 .dhcp6_use_domains = _USE_DOMAINS_INVALID,
414 .dhcp6_use_hostname = true,
415 .dhcp6_use_ntp = -1,
416 .dhcp6_use_captive_portal = true,
417 .dhcp6_use_rapid_commit = true,
418 .dhcp6_send_hostname = true,
419 .dhcp6_duid.type = _DUID_TYPE_INVALID,
420 .dhcp6_client_start_mode = _DHCP6_CLIENT_START_MODE_INVALID,
421 .dhcp6_send_release = true,
422 .dhcp6_pd_prefix_route_type = RTN_UNREACHABLE,
423
424 .dhcp_pd = -1,
425 .dhcp_pd_announce = true,
426 .dhcp_pd_assign = true,
427 .dhcp_pd_manage_temporary_address = true,
428 .dhcp_pd_subnet_id = -1,
429 .dhcp_pd_route_metric = DHCP6PD_ROUTE_METRIC,
430
431 .dhcp_server_bind_to_interface = true,
432 .dhcp_server_emit[SD_DHCP_LEASE_DNS].emit = true,
433 .dhcp_server_emit[SD_DHCP_LEASE_NTP].emit = true,
434 .dhcp_server_emit[SD_DHCP_LEASE_SIP].emit = true,
435 .dhcp_server_emit_router = true,
436 .dhcp_server_emit_timezone = true,
437 .dhcp_server_rapid_commit = true,
438 .dhcp_server_persist_leases = _DHCP_SERVER_PERSIST_LEASES_INVALID,
439
440 .router_lifetime_usec = RADV_DEFAULT_ROUTER_LIFETIME_USEC,
441 .router_dns_lifetime_usec = RADV_DEFAULT_VALID_LIFETIME_USEC,
442 .router_emit_dns = true,
443 .router_emit_domains = true,
444
445 .use_bpdu = -1,
446 .hairpin = -1,
447 .isolated = -1,
448 .fast_leave = -1,
449 .allow_port_to_be_root = -1,
450 .unicast_flood = -1,
451 .multicast_flood = -1,
452 .multicast_to_unicast = -1,
453 .neighbor_suppression = -1,
454 .learning = -1,
455 .bridge_proxy_arp = -1,
456 .bridge_proxy_arp_wifi = -1,
457 .priority = LINK_BRIDGE_PORT_PRIORITY_INVALID,
458 .multicast_router = _MULTICAST_ROUTER_INVALID,
459 .bridge_locked = -1,
460 .bridge_mac_authentication_bypass = -1,
461 .bridge_vlan_tunnel = -1,
462
463 .bridge_vlan_pvid = BRIDGE_VLAN_KEEP_PVID,
464
465 .lldp_mode = LLDP_MODE_ROUTERS_ONLY,
466 .lldp_multicast_mode = _SD_LLDP_MULTICAST_MODE_INVALID,
467
468 .dns_default_route = -1,
469 .llmnr = RESOLVE_SUPPORT_YES,
470 .mdns = RESOLVE_SUPPORT_NO,
471 .dnssec_mode = _DNSSEC_MODE_INVALID,
472 .dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
473
474 /* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
475 .link_local = _ADDRESS_FAMILY_INVALID,
476 .ipv6ll_address_gen_mode = _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID,
477
478 .ip_forwarding = { -1, -1, },
479 .ipv4_accept_local = -1,
480 .ipv4_route_localnet = -1,
481 .ipv6_privacy_extensions = _IPV6_PRIVACY_EXTENSIONS_INVALID,
482 .ipv6_dad_transmits = -1,
483 .ipv6_proxy_ndp = -1,
484 .proxy_arp = -1,
485 .proxy_arp_pvlan = -1,
486 .ipv4_rp_filter = _IP_REVERSE_PATH_FILTER_INVALID,
487 .ipv4_force_igmp_version = _IPV4_FORCE_IGMP_VERSION_INVALID,
488 .mpls_input = -1,
489
490 .ndisc = -1,
491 .ndisc_use_redirect = true,
492 .ndisc_use_dns = -1,
493 .ndisc_use_dnr = -1,
494 .ndisc_use_gateway = true,
495 .ndisc_use_captive_portal = true,
496 .ndisc_use_route_prefix = true,
497 .ndisc_use_autonomous_prefix = true,
498 .ndisc_use_onlink_prefix = true,
499 .ndisc_use_mtu = true,
500 .ndisc_use_hop_limit = true,
501 .ndisc_use_reachable_time = true,
502 .ndisc_use_retransmission_time = true,
503 .ndisc_use_domains = _USE_DOMAINS_INVALID,
504 .ndisc_route_table = RT_TABLE_MAIN,
505 .ndisc_route_metric_high = IPV6RA_ROUTE_METRIC_HIGH,
506 .ndisc_route_metric_medium = IPV6RA_ROUTE_METRIC_MEDIUM,
507 .ndisc_route_metric_low = IPV6RA_ROUTE_METRIC_LOW,
508 .ndisc_start_dhcp6_client = IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES,
509
510 .can_termination = -1,
511
512 .ipoib_mode = _IP_OVER_INFINIBAND_MODE_INVALID,
513 .ipoib_umcast = -1,
514 };
515
516 r = config_parse_many(
517 STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname, /* root = */ NULL,
518 "Match\0"
519 "Link\0"
520 "SR-IOV\0"
521 "Network\0"
522 "Address\0"
523 "Neighbor\0"
524 "IPv6AddressLabel\0"
525 "RoutingPolicyRule\0"
526 "Route\0"
527 "NextHop\0"
528 "DHCP\0" /* compat */
529 "DHCPv4\0"
530 "DHCPv6\0"
531 "DHCPv6PrefixDelegation\0" /* compat */
532 "DHCPPrefixDelegation\0"
533 "DHCPServer\0"
534 "DHCPServerStaticLease\0"
535 "IPv6AcceptRA\0"
536 "IPv6NDPProxyAddress\0"
537 "Bridge\0"
538 "BridgeFDB\0"
539 "BridgeMDB\0"
540 "BridgeVLAN\0"
541 "IPv6SendRA\0"
542 "IPv6PrefixDelegation\0"
543 "IPv6Prefix\0"
544 "IPv6RoutePrefix\0"
545 "IPv6PREF64Prefix\0"
546 "LLDP\0"
547 "TrafficControlQueueingDiscipline\0"
548 "CAN\0"
549 "QDisc\0"
550 "BFIFO\0"
551 "CAKE\0"
552 "ControlledDelay\0"
553 "DeficitRoundRobinScheduler\0"
554 "DeficitRoundRobinSchedulerClass\0"
555 "EnhancedTransmissionSelection\0"
556 "FairQueueing\0"
557 "FairQueueingControlledDelay\0"
558 "FlowQueuePIE\0"
559 "GenericRandomEarlyDetection\0"
560 "HeavyHitterFilter\0"
561 "HierarchyTokenBucket\0"
562 "HierarchyTokenBucketClass\0"
563 "ClassfulMultiQueueing\0"
564 "BandMultiQueueing\0"
565 "NetworkEmulator\0"
566 "PFIFO\0"
567 "PFIFOFast\0"
568 "PFIFOHeadDrop\0"
569 "PIE\0"
570 "QuickFairQueueing\0"
571 "QuickFairQueueingClass\0"
572 "StochasticFairBlue\0"
573 "StochasticFairnessQueueing\0"
574 "TokenBucketFilter\0"
575 "TrivialLinkEqualizer\0",
576 config_item_perf_lookup, network_network_gperf_lookup,
577 CONFIG_PARSE_WARN,
578 network,
579 &network->stats_by_path,
580 &network->dropins);
581 if (r < 0)
582 return r; /* config_parse_many() logs internally. */
583
584 r = network_add_ipv4ll_route(network);
585 if (r < 0)
586 return log_warning_errno(r, "%s: Failed to add IPv4LL route: %m", network->filename);
587
588 r = network_add_default_route_on_device(network);
589 if (r < 0)
590 return log_warning_errno(r, "%s: Failed to add default route on device: %m",
591 network->filename);
592
593 r = network_verify(network);
594 if (r < 0)
595 return r; /* network_verify() logs internally. */
596
597 r = ordered_hashmap_ensure_put(networks, &network_hash_ops, network->name, network);
598 if (r < 0)
599 return log_warning_errno(r, "%s: Failed to store configuration into hashmap: %m", filename);
600
601 TAKE_PTR(network);
602 log_syntax(/* unit = */ NULL, LOG_DEBUG, filename, /* config_line = */ 0, /* error = */ 0, "Successfully loaded.");
603 return 0;
604 }
605
606 int network_load(Manager *manager, OrderedHashmap **ret) {
607 _cleanup_strv_free_ char **files = NULL;
608 OrderedHashmap *networks = NULL;
609 int r;
610
611 assert(manager);
612 assert(ret);
613
614 r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS);
615 if (r < 0)
616 return log_error_errno(r, "Failed to enumerate network files: %m");
617
618 STRV_FOREACH(f, files)
619 (void) network_load_one(manager, &networks, *f);
620
621 *ret = TAKE_PTR(networks);
622 return 0;
623 }
624
625 static bool network_netdev_equal(Network *a, Network *b) {
626 assert(a);
627 assert(b);
628
629 if (a->batadv != b->batadv ||
630 a->bridge != b->bridge ||
631 a->bond != b->bond ||
632 a->vrf != b->vrf ||
633 a->xfrm != b->xfrm)
634 return false;
635
636 if (hashmap_size(a->stacked_netdevs) != hashmap_size(b->stacked_netdevs))
637 return false;
638
639 NetDev *n;
640 HASHMAP_FOREACH(n, a->stacked_netdevs)
641 if (hashmap_get(b->stacked_netdevs, n->ifname) != n)
642 return false;
643
644 return true;
645 }
646
647 int network_reload(Manager *manager) {
648 _cleanup_ordered_hashmap_free_ OrderedHashmap *new_networks = NULL;
649 Network *n, *old;
650 int r;
651
652 assert(manager);
653
654 r = network_load(manager, &new_networks);
655 if (r < 0)
656 return r;
657
658 ORDERED_HASHMAP_FOREACH(n, new_networks) {
659 r = network_get_by_name(manager, n->name, &old);
660 if (r < 0) {
661 log_debug("%s: Found new .network file.", n->filename);
662 continue;
663 }
664
665 if (!stats_by_path_equal(n->stats_by_path, old->stats_by_path)) {
666 log_debug("%s: Found updated .network file.", n->filename);
667 continue;
668 }
669
670 if (!network_netdev_equal(n, old)) {
671 log_debug("%s: Detected update of referenced .netdev file(s).", n->filename);
672 continue;
673 }
674
675 /* Nothing updated, use the existing Network object, and drop the new one. */
676 r = ordered_hashmap_replace(new_networks, old->name, old);
677 if (r < 0)
678 return r;
679
680 network_ref(old);
681 network_unref(n);
682 }
683
684 ordered_hashmap_free_and_replace(manager->networks, new_networks);
685
686 r = manager_build_dhcp_pd_subnet_ids(manager);
687 if (r < 0)
688 return r;
689
690 r = manager_build_nexthop_ids(manager);
691 if (r < 0)
692 return r;
693
694 return 0;
695 }
696
697 int manager_build_dhcp_pd_subnet_ids(Manager *manager) {
698 Network *n;
699 int r;
700
701 assert(manager);
702
703 set_clear(manager->dhcp_pd_subnet_ids);
704
705 ORDERED_HASHMAP_FOREACH(n, manager->networks) {
706 if (n->unmanaged)
707 continue;
708
709 if (!n->dhcp_pd)
710 continue;
711
712 if (n->dhcp_pd_subnet_id < 0)
713 continue;
714
715 r = set_ensure_put(&manager->dhcp_pd_subnet_ids, &uint64_hash_ops, &n->dhcp_pd_subnet_id);
716 if (r < 0)
717 return r;
718 }
719
720 return 0;
721 }
722
723 static Network *network_free(Network *network) {
724 if (!network)
725 return NULL;
726
727 free(network->name);
728 free(network->filename);
729 free(network->description);
730 strv_free(network->dropins);
731 hashmap_free(network->stats_by_path);
732
733 /* conditions */
734 net_match_clear(&network->match);
735 condition_free_list(network->conditions);
736
737 /* link settings */
738 strv_free(network->bind_carrier);
739
740 /* NTP */
741 strv_free(network->ntp);
742
743 /* DNS */
744 for (unsigned i = 0; i < network->n_dns; i++)
745 in_addr_full_free(network->dns[i]);
746 free(network->dns);
747 ordered_set_free(network->search_domains);
748 ordered_set_free(network->route_domains);
749 set_free(network->dnssec_negative_trust_anchors);
750
751 /* DHCP server */
752 free(network->dhcp_server_relay_agent_circuit_id);
753 free(network->dhcp_server_relay_agent_remote_id);
754 free(network->dhcp_server_boot_server_name);
755 free(network->dhcp_server_boot_filename);
756 free(network->dhcp_server_timezone);
757 free(network->dhcp_server_uplink_name);
758 for (sd_dhcp_lease_server_type_t t = 0; t < _SD_DHCP_LEASE_SERVER_TYPE_MAX; t++)
759 free(network->dhcp_server_emit[t].addresses);
760 ordered_hashmap_free(network->dhcp_server_send_options);
761 ordered_hashmap_free(network->dhcp_server_send_vendor_options);
762
763 /* DHCP client */
764 free(network->dhcp_vendor_class_identifier);
765 free(network->dhcp_mudurl);
766 free(network->dhcp_hostname);
767 free(network->dhcp_label);
768 set_free(network->dhcp_deny_listed_ip);
769 set_free(network->dhcp_allow_listed_ip);
770 strv_free(network->dhcp_user_class);
771 set_free(network->dhcp_request_options);
772 ordered_hashmap_free(network->dhcp_client_send_options);
773 ordered_hashmap_free(network->dhcp_client_send_vendor_options);
774 free(network->dhcp_netlabel);
775 nft_set_context_clear(&network->dhcp_nft_set_context);
776
777 /* DHCPv6 client */
778 free(network->dhcp6_mudurl);
779 free(network->dhcp6_hostname);
780 strv_free(network->dhcp6_user_class);
781 strv_free(network->dhcp6_vendor_class);
782 set_free(network->dhcp6_request_options);
783 ordered_hashmap_free(network->dhcp6_client_send_options);
784 ordered_hashmap_free(network->dhcp6_client_send_vendor_options);
785 free(network->dhcp6_netlabel);
786 nft_set_context_clear(&network->dhcp6_nft_set_context);
787
788 /* DHCP PD */
789 free(network->dhcp_pd_uplink_name);
790 set_free(network->dhcp_pd_tokens);
791 free(network->dhcp_pd_netlabel);
792 nft_set_context_clear(&network->dhcp_pd_nft_set_context);
793
794 /* Router advertisement */
795 ordered_set_free(network->router_search_domains);
796 free(network->router_dns);
797 free(network->router_uplink_name);
798
799 /* NDisc */
800 set_free(network->ndisc_deny_listed_router);
801 set_free(network->ndisc_allow_listed_router);
802 set_free(network->ndisc_deny_listed_prefix);
803 set_free(network->ndisc_allow_listed_prefix);
804 set_free(network->ndisc_deny_listed_route_prefix);
805 set_free(network->ndisc_allow_listed_route_prefix);
806 set_free(network->ndisc_tokens);
807 free(network->ndisc_netlabel);
808 nft_set_context_clear(&network->ndisc_nft_set_context);
809
810 /* LLDP */
811 free(network->lldp_mudurl);
812
813 /* netdev */
814 free(network->batadv_name);
815 free(network->bridge_name);
816 free(network->bond_name);
817 free(network->vrf_name);
818 hashmap_free(network->stacked_netdev_names);
819 netdev_unref(network->bridge);
820 netdev_unref(network->bond);
821 netdev_unref(network->vrf);
822 hashmap_free(network->stacked_netdevs);
823
824 /* static configs */
825 set_free(network->ipv6_proxy_ndp_addresses);
826 ordered_hashmap_free(network->addresses_by_section);
827 hashmap_free(network->routes_by_section);
828 ordered_hashmap_free(network->nexthops_by_section);
829 hashmap_free(network->bridge_fdb_entries_by_section);
830 hashmap_free(network->bridge_mdb_entries_by_section);
831 ordered_hashmap_free(network->neighbors_by_section);
832 hashmap_free(network->address_labels_by_section);
833 hashmap_free(network->prefixes_by_section);
834 hashmap_free(network->route_prefixes_by_section);
835 hashmap_free(network->pref64_prefixes_by_section);
836 hashmap_free(network->rules_by_section);
837 hashmap_free(network->dhcp_static_leases_by_section);
838 ordered_hashmap_free(network->sr_iov_by_section);
839 hashmap_free(network->qdiscs_by_section);
840 hashmap_free(network->tclasses_by_section);
841
842 return mfree(network);
843 }
844
845 DEFINE_TRIVIAL_REF_UNREF_FUNC(Network, network, network_free);
846
847 int network_get_by_name(Manager *manager, const char *name, Network **ret) {
848 Network *network;
849
850 assert(manager);
851 assert(name);
852 assert(ret);
853
854 network = ordered_hashmap_get(manager->networks, name);
855 if (!network)
856 return -ENOENT;
857
858 *ret = network;
859
860 return 0;
861 }
862
863 bool network_has_static_ipv6_configurations(Network *network) {
864 Address *address;
865 Route *route;
866 BridgeFDB *fdb;
867 BridgeMDB *mdb;
868 Neighbor *neighbor;
869
870 assert(network);
871
872 ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section)
873 if (address->family == AF_INET6)
874 return true;
875
876 HASHMAP_FOREACH(route, network->routes_by_section)
877 if (route->family == AF_INET6)
878 return true;
879
880 HASHMAP_FOREACH(fdb, network->bridge_fdb_entries_by_section)
881 if (fdb->family == AF_INET6)
882 return true;
883
884 HASHMAP_FOREACH(mdb, network->bridge_mdb_entries_by_section)
885 if (mdb->family == AF_INET6)
886 return true;
887
888 ORDERED_HASHMAP_FOREACH(neighbor, network->neighbors_by_section)
889 if (neighbor->dst_addr.family == AF_INET6)
890 return true;
891
892 if (!hashmap_isempty(network->address_labels_by_section))
893 return true;
894
895 if (!hashmap_isempty(network->prefixes_by_section))
896 return true;
897
898 if (!hashmap_isempty(network->route_prefixes_by_section))
899 return true;
900
901 if (!hashmap_isempty(network->pref64_prefixes_by_section))
902 return true;
903
904 return false;
905 }
906
907 int config_parse_stacked_netdev(
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 _cleanup_free_ char *name = NULL;
920 NetDevKind kind = ltype;
921 Hashmap **h = ASSERT_PTR(data);
922 int r;
923
924 assert(filename);
925 assert(lvalue);
926 assert(rvalue);
927 assert(IN_SET(kind,
928 NETDEV_KIND_IPOIB,
929 NETDEV_KIND_IPVLAN,
930 NETDEV_KIND_IPVTAP,
931 NETDEV_KIND_MACSEC,
932 NETDEV_KIND_MACVLAN,
933 NETDEV_KIND_MACVTAP,
934 NETDEV_KIND_VLAN,
935 NETDEV_KIND_VXLAN,
936 NETDEV_KIND_XFRM,
937 _NETDEV_KIND_TUNNEL));
938
939 if (!ifname_valid(rvalue)) {
940 log_syntax(unit, LOG_WARNING, filename, line, 0,
941 "Invalid netdev name in %s=, ignoring assignment: %s", lvalue, rvalue);
942 return 0;
943 }
944
945 name = strdup(rvalue);
946 if (!name)
947 return log_oom();
948
949 r = hashmap_ensure_put(h, &string_hash_ops_free, name, INT_TO_PTR(kind));
950 if (r == -ENOMEM)
951 return log_oom();
952 if (r < 0)
953 log_syntax(unit, LOG_WARNING, filename, line, r,
954 "Cannot add NetDev '%s' to network, ignoring assignment: %m", name);
955 else if (r == 0)
956 log_syntax(unit, LOG_DEBUG, filename, line, r,
957 "NetDev '%s' specified twice, ignoring.", name);
958 else
959 TAKE_PTR(name);
960
961 return 0;
962 }
963
964 int config_parse_required_for_online(
965 const char *unit,
966 const char *filename,
967 unsigned line,
968 const char *section,
969 unsigned section_line,
970 const char *lvalue,
971 int ltype,
972 const char *rvalue,
973 void *data,
974 void *userdata) {
975
976 Network *network = ASSERT_PTR(userdata);
977 int r;
978
979 assert(filename);
980 assert(lvalue);
981 assert(rvalue);
982
983 if (isempty(rvalue)) {
984 network->required_for_online = -1;
985 network->required_operstate_for_online = LINK_OPERSTATE_RANGE_INVALID;
986 return 0;
987 }
988
989 r = parse_operational_state_range(rvalue, &network->required_operstate_for_online);
990 if (r < 0) {
991 r = parse_boolean(rvalue);
992 if (r < 0) {
993 log_syntax(unit, LOG_WARNING, filename, line, r,
994 "Failed to parse %s= setting, ignoring assignment: %s",
995 lvalue, rvalue);
996 return 0;
997 }
998
999 network->required_for_online = r;
1000 network->required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT;
1001 return 0;
1002 }
1003
1004 network->required_for_online = true;
1005 return 0;
1006 }
1007
1008 int config_parse_link_group(
1009 const char *unit,
1010 const char *filename,
1011 unsigned line,
1012 const char *section,
1013 unsigned section_line,
1014 const char *lvalue,
1015 int ltype,
1016 const char *rvalue,
1017 void *data,
1018 void *userdata) {
1019
1020 Network *network = ASSERT_PTR(userdata);
1021 int r;
1022 int32_t group;
1023
1024 assert(filename);
1025 assert(lvalue);
1026 assert(rvalue);
1027
1028 if (isempty(rvalue)) {
1029 network->group = -1;
1030 return 0;
1031 }
1032
1033 r = safe_atoi32(rvalue, &group);
1034 if (r < 0) {
1035 log_syntax(unit, LOG_WARNING, filename, line, r,
1036 "Failed to parse Group=, ignoring assignment: %s", rvalue);
1037 return 0;
1038 }
1039
1040 if (group < 0) {
1041 log_syntax(unit, LOG_WARNING, filename, line, r,
1042 "Value of Group= must be in the range 0…2147483647, ignoring assignment: %s", rvalue);
1043 return 0;
1044 }
1045
1046 network->group = group;
1047 return 0;
1048 }
1049
1050 int config_parse_ignore_carrier_loss(
1051 const char *unit,
1052 const char *filename,
1053 unsigned line,
1054 const char *section,
1055 unsigned section_line,
1056 const char *lvalue,
1057 int ltype,
1058 const char *rvalue,
1059 void *data,
1060 void *userdata) {
1061
1062 Network *network = ASSERT_PTR(userdata);
1063 usec_t usec;
1064 int r;
1065
1066 assert(filename);
1067 assert(lvalue);
1068 assert(rvalue);
1069
1070 if (isempty(rvalue)) {
1071 network->ignore_carrier_loss_set = false;
1072 return 0;
1073 }
1074
1075 r = parse_boolean(rvalue);
1076 if (r >= 0) {
1077 network->ignore_carrier_loss_set = true;
1078 network->ignore_carrier_loss_usec = r > 0 ? USEC_INFINITY : 0;
1079 return 0;
1080 }
1081
1082 r = parse_sec(rvalue, &usec);
1083 if (r < 0) {
1084 log_syntax(unit, LOG_WARNING, filename, line, r,
1085 "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
1086 return 0;
1087 }
1088
1089 network->ignore_carrier_loss_set = true;
1090 network->ignore_carrier_loss_usec = usec;
1091 return 0;
1092 }
1093
1094 int config_parse_keep_configuration(
1095 const char *unit,
1096 const char *filename,
1097 unsigned line,
1098 const char *section,
1099 unsigned section_line,
1100 const char *lvalue,
1101 int ltype,
1102 const char *rvalue,
1103 void *data,
1104 void *userdata) {
1105
1106 KeepConfiguration t, *k = ASSERT_PTR(data);
1107 Network *network = ASSERT_PTR(userdata);
1108
1109 if (isempty(rvalue)) {
1110 *k = ASSERT_PTR(network->manager)->keep_configuration;
1111 return 0;
1112 }
1113
1114 /* backward compatibility */
1115 if (streq(rvalue, "dhcp")) {
1116 *k = KEEP_CONFIGURATION_DYNAMIC;
1117 return 0;
1118 }
1119
1120 if (streq(rvalue, "dhcp-on-stop")) {
1121 *k = KEEP_CONFIGURATION_DYNAMIC_ON_STOP;
1122 return 0;
1123 }
1124
1125 t = keep_configuration_from_string(rvalue);
1126 if (t < 0)
1127 return log_syntax_parse_error(unit, filename, line, t, lvalue, rvalue);
1128
1129 *k = t;
1130 return 0;
1131 }
1132
1133 DEFINE_CONFIG_PARSE_ENUM(config_parse_required_family_for_online, link_required_address_family, AddressFamily);
1134
1135 static const char* const keep_configuration_table[_KEEP_CONFIGURATION_MAX] = {
1136 [KEEP_CONFIGURATION_NO] = "no",
1137 [KEEP_CONFIGURATION_DYNAMIC_ON_STOP] = "dynamic-on-stop",
1138 [KEEP_CONFIGURATION_DYNAMIC] = "dynamic",
1139 [KEEP_CONFIGURATION_STATIC] = "static",
1140 [KEEP_CONFIGURATION_YES] = "yes",
1141 };
1142
1143 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration, KeepConfiguration, KEEP_CONFIGURATION_YES);
1144
1145 static const char* const activation_policy_table[_ACTIVATION_POLICY_MAX] = {
1146 [ACTIVATION_POLICY_UP] = "up",
1147 [ACTIVATION_POLICY_ALWAYS_UP] = "always-up",
1148 [ACTIVATION_POLICY_MANUAL] = "manual",
1149 [ACTIVATION_POLICY_ALWAYS_DOWN] = "always-down",
1150 [ACTIVATION_POLICY_DOWN] = "down",
1151 [ACTIVATION_POLICY_BOUND] = "bound",
1152 };
1153
1154 DEFINE_STRING_TABLE_LOOKUP(activation_policy, ActivationPolicy);
1155 DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy, activation_policy, ActivationPolicy);