]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/udev/net/link-config.c
network: Show network and link file dropins in networkctl status
[thirdparty/systemd.git] / src / udev / net / link-config.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <linux/netdevice.h>
4 #include <netinet/ether.h>
5 #include <unistd.h>
6
7 #include "sd-device.h"
8 #include "sd-netlink.h"
9
10 #include "alloc-util.h"
11 #include "arphrd-util.h"
12 #include "conf-files.h"
13 #include "conf-parser.h"
14 #include "constants.h"
15 #include "creds-util.h"
16 #include "device-private.h"
17 #include "device-util.h"
18 #include "ethtool-util.h"
19 #include "fd-util.h"
20 #include "fileio.h"
21 #include "link-config.h"
22 #include "log-link.h"
23 #include "memory-util.h"
24 #include "net-condition.h"
25 #include "netif-sriov.h"
26 #include "netif-util.h"
27 #include "netlink-util.h"
28 #include "parse-util.h"
29 #include "path-lookup.h"
30 #include "path-util.h"
31 #include "proc-cmdline.h"
32 #include "random-util.h"
33 #include "stat-util.h"
34 #include "string-table.h"
35 #include "string-util.h"
36 #include "strv.h"
37 #include "utf8.h"
38
39 struct LinkConfigContext {
40 LIST_HEAD(LinkConfig, configs);
41 int ethtool_fd;
42 Hashmap *stats_by_path;
43 };
44
45 static LinkConfig* link_config_free(LinkConfig *config) {
46 if (!config)
47 return NULL;
48
49 free(config->filename);
50 strv_free(config->dropins);
51
52 net_match_clear(&config->match);
53 condition_free_list(config->conditions);
54
55 free(config->description);
56 free(config->name_policy);
57 free(config->name);
58 strv_free(config->alternative_names);
59 free(config->alternative_names_policy);
60 free(config->alias);
61 free(config->wol_password_file);
62 erase_and_free(config->wol_password);
63
64 ordered_hashmap_free_with_destructor(config->sr_iov_by_section, sr_iov_free);
65
66 return mfree(config);
67 }
68
69 DEFINE_TRIVIAL_CLEANUP_FUNC(LinkConfig*, link_config_free);
70
71 static void link_configs_free(LinkConfigContext *ctx) {
72 if (!ctx)
73 return;
74
75 ctx->stats_by_path = hashmap_free(ctx->stats_by_path);
76
77 LIST_FOREACH(configs, config, ctx->configs)
78 link_config_free(config);
79 }
80
81 LinkConfigContext *link_config_ctx_free(LinkConfigContext *ctx) {
82 if (!ctx)
83 return NULL;
84
85 safe_close(ctx->ethtool_fd);
86 link_configs_free(ctx);
87 return mfree(ctx);
88 }
89
90 int link_config_ctx_new(LinkConfigContext **ret) {
91 _cleanup_(link_config_ctx_freep) LinkConfigContext *ctx = NULL;
92
93 if (!ret)
94 return -EINVAL;
95
96 ctx = new(LinkConfigContext, 1);
97 if (!ctx)
98 return -ENOMEM;
99
100 *ctx = (LinkConfigContext) {
101 .ethtool_fd = -EBADF,
102 };
103
104 *ret = TAKE_PTR(ctx);
105
106 return 0;
107 }
108
109 static int link_parse_wol_password(LinkConfig *config, const char *str) {
110 _cleanup_(erase_and_freep) uint8_t *p = NULL;
111 int r;
112
113 assert(config);
114 assert(str);
115
116 assert_cc(sizeof(struct ether_addr) == SOPASS_MAX);
117
118 p = new(uint8_t, SOPASS_MAX);
119 if (!p)
120 return -ENOMEM;
121
122 /* Reuse parse_ether_addr(), as their formats are equivalent. */
123 r = parse_ether_addr(str, (struct ether_addr*) p);
124 if (r < 0)
125 return r;
126
127 erase_and_free(config->wol_password);
128 config->wol_password = TAKE_PTR(p);
129 return 0;
130 }
131
132 static int link_read_wol_password_from_file(LinkConfig *config) {
133 _cleanup_(erase_and_freep) char *password = NULL;
134 int r;
135
136 assert(config);
137
138 if (!config->wol_password_file)
139 return 0;
140
141 r = read_full_file_full(
142 AT_FDCWD, config->wol_password_file, UINT64_MAX, SIZE_MAX,
143 READ_FULL_FILE_SECURE | READ_FULL_FILE_WARN_WORLD_READABLE | READ_FULL_FILE_CONNECT_SOCKET,
144 NULL, &password, NULL);
145 if (r < 0)
146 return r;
147
148 return link_parse_wol_password(config, password);
149 }
150
151 static int link_read_wol_password_from_cred(LinkConfig *config) {
152 _cleanup_free_ char *base = NULL, *cred_name = NULL;
153 _cleanup_(erase_and_freep) char *password = NULL;
154 int r;
155
156 assert(config);
157 assert(config->filename);
158
159 if (config->wol == UINT32_MAX)
160 return 0; /* WakeOnLan= is not specified. */
161 if (!FLAGS_SET(config->wol, WAKE_MAGICSECURE))
162 return 0; /* secureon is not specified in WakeOnLan=. */
163 if (config->wol_password)
164 return 0; /* WakeOnLanPassword= is specified. */
165 if (config->wol_password_file)
166 return 0; /* a file name is specified in WakeOnLanPassword=, but failed to read it. */
167
168 r = path_extract_filename(config->filename, &base);
169 if (r < 0)
170 return r;
171
172 cred_name = strjoin(base, ".wol.password");
173 if (!cred_name)
174 return -ENOMEM;
175
176 r = read_credential(cred_name, (void**) &password, NULL);
177 if (r == -ENOENT)
178 r = read_credential("wol.password", (void**) &password, NULL);
179 if (r < 0)
180 return r;
181
182 return link_parse_wol_password(config, password);
183 }
184
185 static int link_adjust_wol_options(LinkConfig *config) {
186 int r;
187
188 assert(config);
189
190 r = link_read_wol_password_from_file(config);
191 if (r == -ENOMEM)
192 return log_oom();
193 if (r < 0)
194 log_warning_errno(r, "Failed to read WakeOnLan password from %s, ignoring: %m", config->wol_password_file);
195
196 r = link_read_wol_password_from_cred(config);
197 if (r == -ENOMEM)
198 return log_oom();
199 if (r < 0)
200 log_warning_errno(r, "Failed to read WakeOnLan password from credential, ignoring: %m");
201
202 if (config->wol != UINT32_MAX && config->wol_password)
203 /* Enable WAKE_MAGICSECURE flag when WakeOnLanPassword=. Note that when
204 * WakeOnLanPassword= is set without WakeOnLan=, then ethtool_set_wol() enables
205 * WAKE_MAGICSECURE flag and other flags are not changed. */
206 config->wol |= WAKE_MAGICSECURE;
207
208 return 0;
209 }
210
211 int link_load_one(LinkConfigContext *ctx, const char *filename) {
212 _cleanup_(link_config_freep) LinkConfig *config = NULL;
213 _cleanup_hashmap_free_ Hashmap *stats_by_path = NULL;
214 _cleanup_free_ char *name = NULL;
215 const char *dropin_dirname;
216 size_t i;
217 int r;
218
219 assert(ctx);
220 assert(filename);
221
222 r = null_or_empty_path(filename);
223 if (r < 0)
224 return log_warning_errno(r, "Failed to check if \"%s\" is empty: %m", filename);
225 if (r > 0) {
226 log_debug("Skipping empty file: %s", filename);
227 return 0;
228 }
229
230 name = strdup(filename);
231 if (!name)
232 return log_oom();
233
234 config = new(LinkConfig, 1);
235 if (!config)
236 return log_oom();
237
238 *config = (LinkConfig) {
239 .filename = TAKE_PTR(name),
240 .mac_address_policy = MAC_ADDRESS_POLICY_NONE,
241 .wol = UINT32_MAX, /* UINT32_MAX means do not change WOL setting. */
242 .duplex = _DUP_INVALID,
243 .port = _NET_DEV_PORT_INVALID,
244 .autonegotiation = -1,
245 .rx_flow_control = -1,
246 .tx_flow_control = -1,
247 .autoneg_flow_control = -1,
248 .txqueuelen = UINT32_MAX,
249 .coalesce.use_adaptive_rx_coalesce = -1,
250 .coalesce.use_adaptive_tx_coalesce = -1,
251 .mdi = ETH_TP_MDI_INVALID,
252 .sr_iov_num_vfs = UINT32_MAX,
253 };
254
255 for (i = 0; i < ELEMENTSOF(config->features); i++)
256 config->features[i] = -1;
257
258 dropin_dirname = strjoina(basename(filename), ".d");
259 r = config_parse_many(
260 STRV_MAKE_CONST(filename),
261 NETWORK_DIRS,
262 dropin_dirname,
263 "Match\0"
264 "Link\0"
265 "SR-IOV\0",
266 config_item_perf_lookup, link_config_gperf_lookup,
267 CONFIG_PARSE_WARN, config, &stats_by_path,
268 &config->dropins);
269 if (r < 0)
270 return r; /* config_parse_many() logs internally. */
271
272 if (ctx->stats_by_path) {
273 r = hashmap_move(ctx->stats_by_path, stats_by_path);
274 if (r < 0)
275 log_warning_errno(r, "Failed to save stats of '%s' and its drop-in configs, ignoring: %m", filename);
276 } else
277 ctx->stats_by_path = TAKE_PTR(stats_by_path);
278
279 if (net_match_is_empty(&config->match) && !config->conditions) {
280 log_warning("%s: No valid settings found in the [Match] section, ignoring file. "
281 "To match all interfaces, add OriginalName=* in the [Match] section.",
282 filename);
283 return 0;
284 }
285
286 if (!condition_test_list(config->conditions, environ, NULL, NULL, NULL)) {
287 log_debug("%s: Conditions do not match the system environment, skipping.", filename);
288 return 0;
289 }
290
291 if (IN_SET(config->mac_address_policy, MAC_ADDRESS_POLICY_PERSISTENT, MAC_ADDRESS_POLICY_RANDOM) &&
292 config->hw_addr.length > 0)
293 log_warning("%s: MACAddress= in [Link] section will be ignored when MACAddressPolicy= "
294 "is set to \"persistent\" or \"random\".",
295 filename);
296
297 r = link_adjust_wol_options(config);
298 if (r < 0)
299 return r; /* link_adjust_wol_options() logs internally. */
300
301 r = sr_iov_drop_invalid_sections(config->sr_iov_num_vfs, config->sr_iov_by_section);
302 if (r < 0)
303 return r; /* sr_iov_drop_invalid_sections() logs internally. */
304
305 log_debug("Parsed configuration file \"%s\"", filename);
306
307 LIST_PREPEND(configs, ctx->configs, TAKE_PTR(config));
308 return 0;
309 }
310
311 static int device_unsigned_attribute(sd_device *device, const char *attr, unsigned *type) {
312 const char *s;
313 int r;
314
315 r = sd_device_get_sysattr_value(device, attr, &s);
316 if (r < 0)
317 return log_device_debug_errno(device, r, "Failed to query %s: %m", attr);
318
319 r = safe_atou(s, type);
320 if (r < 0)
321 return log_device_warning_errno(device, r, "Failed to parse %s \"%s\": %m", attr, s);
322
323 log_device_debug(device, "Device has %s=%u", attr, *type);
324 return 0;
325 }
326
327 int link_config_load(LinkConfigContext *ctx) {
328 _cleanup_strv_free_ char **files = NULL;
329 int r;
330
331 assert(ctx);
332
333 link_configs_free(ctx);
334
335 r = conf_files_list_strv(&files, ".link", NULL, 0, NETWORK_DIRS);
336 if (r < 0)
337 return log_error_errno(r, "failed to enumerate link files: %m");
338
339 STRV_FOREACH_BACKWARDS(f, files)
340 (void) link_load_one(ctx, *f);
341
342 return 0;
343 }
344
345 bool link_config_should_reload(LinkConfigContext *ctx) {
346 _cleanup_hashmap_free_ Hashmap *stats_by_path = NULL;
347 int r;
348
349 assert(ctx);
350
351 r = config_get_stats_by_path(".link", NULL, 0, NETWORK_DIRS, /* check_dropins = */ true, &stats_by_path);
352 if (r < 0) {
353 log_warning_errno(r, "Failed to get stats of .link files, ignoring: %m");
354 return true;
355 }
356
357 return !stats_by_path_equal(ctx->stats_by_path, stats_by_path);
358 }
359
360 Link *link_free(Link *link) {
361 if (!link)
362 return NULL;
363
364 sd_device_unref(link->device);
365 free(link->kind);
366 free(link->driver);
367 return mfree(link);
368 }
369
370 int link_new(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device, Link **ret) {
371 _cleanup_(link_freep) Link *link = NULL;
372 int r;
373
374 assert(ctx);
375 assert(rtnl);
376 assert(device);
377 assert(ret);
378
379 link = new(Link, 1);
380 if (!link)
381 return -ENOMEM;
382
383 *link = (Link) {
384 .device = sd_device_ref(device),
385 };
386
387 r = sd_device_get_sysname(device, &link->ifname);
388 if (r < 0)
389 return r;
390
391 r = sd_device_get_ifindex(device, &link->ifindex);
392 if (r < 0)
393 return r;
394
395 r = sd_device_get_action(device, &link->action);
396 if (r < 0)
397 return r;
398
399 r = device_unsigned_attribute(device, "name_assign_type", &link->name_assign_type);
400 if (r < 0)
401 log_link_debug_errno(link, r, "Failed to get \"name_assign_type\" attribute, ignoring: %m");
402
403 r = device_unsigned_attribute(device, "addr_assign_type", &link->addr_assign_type);
404 if (r < 0)
405 log_link_debug_errno(link, r, "Failed to get \"addr_assign_type\" attribute, ignoring: %m");
406
407 r = rtnl_get_link_info(rtnl, link->ifindex, &link->iftype, &link->flags,
408 &link->kind, &link->hw_addr, &link->permanent_hw_addr);
409 if (r < 0)
410 return r;
411
412 if (link->hw_addr.length > 0 && link->permanent_hw_addr.length == 0) {
413 r = ethtool_get_permanent_hw_addr(&ctx->ethtool_fd, link->ifname, &link->permanent_hw_addr);
414 if (r < 0)
415 log_link_debug_errno(link, r, "Failed to get permanent hardware address, ignoring: %m");
416 }
417
418 r = ethtool_get_driver(&ctx->ethtool_fd, link->ifname, &link->driver);
419 if (r < 0)
420 log_link_debug_errno(link, r, "Failed to get driver, ignoring: %m");
421
422 *ret = TAKE_PTR(link);
423 return 0;
424 }
425
426 int link_get_config(LinkConfigContext *ctx, Link *link) {
427 int r;
428
429 assert(ctx);
430 assert(link);
431
432 /* Do not configure loopback interfaces by .link files. */
433 if (link->flags & IFF_LOOPBACK)
434 return -ENOENT;
435
436 LIST_FOREACH(configs, config, ctx->configs) {
437 r = net_match_config(
438 &config->match,
439 link->device,
440 &link->hw_addr,
441 &link->permanent_hw_addr,
442 link->driver,
443 link->iftype,
444 link->kind,
445 link->ifname,
446 /* alternative_names = */ NULL,
447 /* wlan_iftype = */ 0,
448 /* ssid = */ NULL,
449 /* bssid = */ NULL);
450 if (r < 0)
451 return r;
452 if (r == 0)
453 continue;
454
455 if (config->match.ifname && !strv_contains(config->match.ifname, "*") && link->name_assign_type == NET_NAME_ENUM)
456 log_link_warning(link, "Config file %s is applied to device based on potentially unpredictable interface name.",
457 config->filename);
458 else
459 log_link_debug(link, "Config file %s is applied", config->filename);
460
461 link->config = config;
462 return 0;
463 }
464
465 return -ENOENT;
466 }
467
468 static int link_apply_ethtool_settings(Link *link, int *ethtool_fd) {
469 LinkConfig *config;
470 const char *name;
471 int r;
472
473 assert(link);
474 assert(link->config);
475 assert(ethtool_fd);
476
477 config = link->config;
478 name = link->ifname;
479
480 r = ethtool_set_glinksettings(ethtool_fd, name,
481 config->autonegotiation, config->advertise,
482 config->speed, config->duplex, config->port, config->mdi);
483 if (r < 0) {
484 if (config->autonegotiation >= 0)
485 log_link_warning_errno(link, r, "Could not %s auto negotiation, ignoring: %m",
486 enable_disable(config->autonegotiation));
487
488 if (!eqzero(config->advertise))
489 log_link_warning_errno(link, r, "Could not set advertise mode, ignoring: %m");
490
491 if (config->speed > 0)
492 log_link_warning_errno(link, r, "Could not set speed to %"PRIu64"Mbps, ignoring: %m",
493 DIV_ROUND_UP(config->speed, 1000000));
494
495 if (config->duplex >= 0)
496 log_link_warning_errno(link, r, "Could not set duplex to %s, ignoring: %m",
497 duplex_to_string(config->duplex));
498
499 if (config->port >= 0)
500 log_link_warning_errno(link, r, "Could not set port to '%s', ignoring: %m",
501 port_to_string(config->port));
502
503 if (config->mdi != ETH_TP_MDI_INVALID)
504 log_link_warning_errno(link, r, "Could not set MDI-X to '%s', ignoring: %m",
505 mdi_to_string(config->mdi));
506 }
507
508 r = ethtool_set_wol(ethtool_fd, name, config->wol, config->wol_password);
509 if (r < 0) {
510 _cleanup_free_ char *str = NULL;
511
512 (void) wol_options_to_string_alloc(config->wol, &str);
513 log_link_warning_errno(link, r, "Could not set WakeOnLan%s%s, ignoring: %m",
514 isempty(str) ? "" : " to ", strempty(str));
515 }
516
517 r = ethtool_set_features(ethtool_fd, name, config->features);
518 if (r < 0)
519 log_link_warning_errno(link, r, "Could not set offload features, ignoring: %m");
520
521 r = ethtool_set_channels(ethtool_fd, name, &config->channels);
522 if (r < 0)
523 log_link_warning_errno(link, r, "Could not set channels, ignoring: %m");
524
525 r = ethtool_set_nic_buffer_size(ethtool_fd, name, &config->ring);
526 if (r < 0)
527 log_link_warning_errno(link, r, "Could not set ring buffer, ignoring: %m");
528
529 r = ethtool_set_flow_control(ethtool_fd, name, config->rx_flow_control, config->tx_flow_control, config->autoneg_flow_control);
530 if (r < 0)
531 log_link_warning_errno(link, r, "Could not set flow control, ignoring: %m");
532
533 r = ethtool_set_nic_coalesce_settings(ethtool_fd, name, &config->coalesce);
534 if (r < 0)
535 log_link_warning_errno(link, r, "Could not set coalesce settings, ignoring: %m");
536
537 return 0;
538 }
539
540 static bool hw_addr_is_valid(Link *link, const struct hw_addr_data *hw_addr) {
541 assert(link);
542 assert(hw_addr);
543
544 switch (link->iftype) {
545 case ARPHRD_ETHER:
546 /* Refuse all zero and all 0xFF. */
547 assert(hw_addr->length == ETH_ALEN);
548 return !ether_addr_is_null(&hw_addr->ether) && !ether_addr_is_broadcast(&hw_addr->ether);
549
550 case ARPHRD_INFINIBAND:
551 /* The last 8 bytes cannot be zero*/
552 assert(hw_addr->length == INFINIBAND_ALEN);
553 return !memeqzero(hw_addr->bytes + INFINIBAND_ALEN - 8, 8);
554
555 default:
556 assert_not_reached();
557 }
558 }
559
560 static int link_generate_new_hw_addr(Link *link, struct hw_addr_data *ret) {
561 struct hw_addr_data hw_addr = HW_ADDR_NULL;
562 bool is_static = false;
563 uint8_t *p;
564 size_t len;
565 int r;
566
567 assert(link);
568 assert(link->config);
569 assert(link->device);
570 assert(ret);
571
572 if (link->hw_addr.length == 0)
573 goto finalize;
574
575 if (link->config->mac_address_policy == MAC_ADDRESS_POLICY_NONE) {
576 log_link_debug(link, "Using static MAC address.");
577 hw_addr = link->config->hw_addr;
578 is_static = true;
579 goto finalize;
580 }
581
582 if (!IN_SET(link->iftype, ARPHRD_ETHER, ARPHRD_INFINIBAND))
583 goto finalize;
584
585 switch (link->addr_assign_type) {
586 case NET_ADDR_SET:
587 log_link_debug(link, "MAC address on the device already set by userspace.");
588 goto finalize;
589 case NET_ADDR_STOLEN:
590 log_link_debug(link, "MAC address on the device already set based on another device.");
591 goto finalize;
592 case NET_ADDR_RANDOM:
593 case NET_ADDR_PERM:
594 break;
595 default:
596 log_link_warning(link, "Unknown addr_assign_type %u, ignoring", link->addr_assign_type);
597 goto finalize;
598 }
599
600 if ((link->config->mac_address_policy == MAC_ADDRESS_POLICY_RANDOM) == (link->addr_assign_type == NET_ADDR_RANDOM)) {
601 log_link_debug(link, "MAC address on the device already matches policy \"%s\".",
602 mac_address_policy_to_string(link->config->mac_address_policy));
603 goto finalize;
604 }
605
606 hw_addr = (struct hw_addr_data) {
607 .length = arphrd_to_hw_addr_len(link->iftype),
608 };
609
610 switch (link->iftype) {
611 case ARPHRD_ETHER:
612 p = hw_addr.bytes;
613 len = hw_addr.length;
614 break;
615 case ARPHRD_INFINIBAND:
616 p = hw_addr.bytes + INFINIBAND_ALEN - 8;
617 len = 8;
618 break;
619 default:
620 assert_not_reached();
621 }
622
623 if (link->config->mac_address_policy == MAC_ADDRESS_POLICY_RANDOM)
624 /* We require genuine randomness here, since we want to make sure we won't collide with other
625 * systems booting up at the very same time. */
626 for (;;) {
627 random_bytes(p, len);
628 if (hw_addr_is_valid(link, &hw_addr))
629 break;
630 }
631
632 else {
633 uint64_t result;
634
635 r = net_get_unique_predictable_data(link->device,
636 naming_scheme_has(NAMING_STABLE_VIRTUAL_MACS),
637 &result);
638 if (r < 0)
639 return log_link_warning_errno(link, r, "Could not generate persistent MAC address: %m");
640
641 assert(len <= sizeof(result));
642 memcpy(p, &result, len);
643 if (!hw_addr_is_valid(link, &hw_addr))
644 return log_link_warning_errno(link, SYNTHETIC_ERRNO(EINVAL),
645 "Could not generate valid persistent MAC address: %m");
646 }
647
648 finalize:
649
650 r = net_verify_hardware_address(link->ifname, is_static, link->iftype, &link->hw_addr, &hw_addr);
651 if (r < 0)
652 return r;
653
654 if (hw_addr_equal(&link->hw_addr, &hw_addr)) {
655 *ret = HW_ADDR_NULL;
656 return 0;
657 }
658
659 if (hw_addr.length > 0)
660 log_link_debug(link, "Applying %s MAC address: %s",
661 link->config->mac_address_policy == MAC_ADDRESS_POLICY_NONE ? "static" :
662 mac_address_policy_to_string(link->config->mac_address_policy),
663 HW_ADDR_TO_STR(&hw_addr));
664
665 *ret = hw_addr;
666 return 0;
667 }
668
669 static int link_apply_rtnl_settings(Link *link, sd_netlink **rtnl) {
670 struct hw_addr_data hw_addr = {};
671 LinkConfig *config;
672 int r;
673
674 assert(link);
675 assert(link->config);
676 assert(rtnl);
677
678 config = link->config;
679
680 (void) link_generate_new_hw_addr(link, &hw_addr);
681
682 r = rtnl_set_link_properties(rtnl, link->ifindex, config->alias, &hw_addr,
683 config->txqueues, config->rxqueues, config->txqueuelen,
684 config->mtu, config->gso_max_size, config->gso_max_segments);
685 if (r < 0)
686 log_link_warning_errno(link, r,
687 "Could not set Alias=, MACAddress=/MACAddressPolicy=, "
688 "TransmitQueues=, ReceiveQueues=, TransmitQueueLength=, MTUBytes=, "
689 "GenericSegmentOffloadMaxBytes= or GenericSegmentOffloadMaxSegments=, "
690 "ignoring: %m");
691
692 return 0;
693 }
694
695 static bool enable_name_policy(void) {
696 static int cached = -1;
697 bool b;
698 int r;
699
700 if (cached >= 0)
701 return cached;
702
703 r = proc_cmdline_get_bool("net.ifnames", &b);
704 if (r < 0)
705 log_warning_errno(r, "Failed to parse net.ifnames= kernel command line option, ignoring: %m");
706 if (r <= 0)
707 return (cached = true);
708
709 if (!b)
710 log_info("Network interface NamePolicy= disabled on kernel command line.");
711
712 return (cached = b);
713 }
714
715 static int link_generate_new_name(Link *link) {
716 LinkConfig *config;
717 sd_device *device;
718
719 assert(link);
720 assert(link->config);
721 assert(link->device);
722
723 config = link->config;
724 device = link->device;
725
726 if (link->action == SD_DEVICE_MOVE) {
727 log_link_debug(link, "Skipping to apply Name= and NamePolicy= on '%s' uevent.",
728 device_action_to_string(link->action));
729 goto no_rename;
730 }
731
732 if (IN_SET(link->name_assign_type, NET_NAME_USER, NET_NAME_RENAMED) &&
733 !naming_scheme_has(NAMING_ALLOW_RERENAMES)) {
734 log_link_debug(link, "Device already has a name given by userspace, not renaming.");
735 goto no_rename;
736 }
737
738 if (enable_name_policy() && config->name_policy)
739 for (NamePolicy *policy = config->name_policy; *policy != _NAMEPOLICY_INVALID; policy++) {
740 const char *new_name = NULL;
741
742 switch (*policy) {
743 case NAMEPOLICY_KERNEL:
744 if (link->name_assign_type != NET_NAME_PREDICTABLE)
745 continue;
746
747 /* The kernel claims to have given a predictable name, keep it. */
748 log_link_debug(link, "Policy *%s*: keeping predictable kernel name",
749 name_policy_to_string(*policy));
750 goto no_rename;
751 case NAMEPOLICY_KEEP:
752 if (!IN_SET(link->name_assign_type, NET_NAME_USER, NET_NAME_RENAMED))
753 continue;
754
755 log_link_debug(link, "Policy *%s*: keeping existing userspace name",
756 name_policy_to_string(*policy));
757 goto no_rename;
758 case NAMEPOLICY_DATABASE:
759 (void) sd_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE", &new_name);
760 break;
761 case NAMEPOLICY_ONBOARD:
762 (void) sd_device_get_property_value(device, "ID_NET_NAME_ONBOARD", &new_name);
763 break;
764 case NAMEPOLICY_SLOT:
765 (void) sd_device_get_property_value(device, "ID_NET_NAME_SLOT", &new_name);
766 break;
767 case NAMEPOLICY_PATH:
768 (void) sd_device_get_property_value(device, "ID_NET_NAME_PATH", &new_name);
769 break;
770 case NAMEPOLICY_MAC:
771 (void) sd_device_get_property_value(device, "ID_NET_NAME_MAC", &new_name);
772 break;
773 default:
774 assert_not_reached();
775 }
776 if (ifname_valid(new_name)) {
777 log_link_debug(link, "Policy *%s* yields \"%s\".", name_policy_to_string(*policy), new_name);
778 link->new_name = new_name;
779 return 0;
780 }
781 }
782
783 if (link->config->name) {
784 log_link_debug(link, "Policies didn't yield a name, using specified Name=%s.", link->config->name);
785 link->new_name = link->config->name;
786 return 0;
787 }
788
789 log_link_debug(link, "Policies didn't yield a name and Name= is not given, not renaming.");
790 no_rename:
791 link->new_name = link->ifname;
792 return 0;
793 }
794
795 static int link_apply_alternative_names(Link *link, sd_netlink **rtnl) {
796 _cleanup_strv_free_ char **altnames = NULL, **current_altnames = NULL;
797 LinkConfig *config;
798 sd_device *device;
799 int r;
800
801 assert(link);
802 assert(link->config);
803 assert(link->device);
804 assert(rtnl);
805
806 config = link->config;
807 device = link->device;
808
809 if (config->alternative_names) {
810 altnames = strv_copy(config->alternative_names);
811 if (!altnames)
812 return log_oom();
813 }
814
815 if (config->alternative_names_policy)
816 for (NamePolicy *p = config->alternative_names_policy; *p != _NAMEPOLICY_INVALID; p++) {
817 const char *n = NULL;
818
819 switch (*p) {
820 case NAMEPOLICY_DATABASE:
821 (void) sd_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE", &n);
822 break;
823 case NAMEPOLICY_ONBOARD:
824 (void) sd_device_get_property_value(device, "ID_NET_NAME_ONBOARD", &n);
825 break;
826 case NAMEPOLICY_SLOT:
827 (void) sd_device_get_property_value(device, "ID_NET_NAME_SLOT", &n);
828 break;
829 case NAMEPOLICY_PATH:
830 (void) sd_device_get_property_value(device, "ID_NET_NAME_PATH", &n);
831 break;
832 case NAMEPOLICY_MAC:
833 (void) sd_device_get_property_value(device, "ID_NET_NAME_MAC", &n);
834 break;
835 default:
836 assert_not_reached();
837 }
838 if (!isempty(n)) {
839 r = strv_extend(&altnames, n);
840 if (r < 0)
841 return log_oom();
842 }
843 }
844
845 strv_remove(altnames, link->ifname);
846
847 r = rtnl_get_link_alternative_names(rtnl, link->ifindex, &current_altnames);
848 if (r < 0)
849 log_link_debug_errno(link, r, "Failed to get alternative names, ignoring: %m");
850
851 STRV_FOREACH(p, current_altnames)
852 strv_remove(altnames, *p);
853
854 strv_uniq(altnames);
855 strv_sort(altnames);
856 r = rtnl_set_link_alternative_names(rtnl, link->ifindex, altnames);
857 if (r < 0)
858 log_link_full_errno(link, r == -EOPNOTSUPP ? LOG_DEBUG : LOG_WARNING, r,
859 "Could not set AlternativeName= or apply AlternativeNamesPolicy=, ignoring: %m");
860
861 return 0;
862 }
863
864 static int sr_iov_configure(Link *link, sd_netlink **rtnl, SRIOV *sr_iov) {
865 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
866 int r;
867
868 assert(link);
869 assert(rtnl);
870 assert(link->ifindex > 0);
871
872 if (!*rtnl) {
873 r = sd_netlink_open(rtnl);
874 if (r < 0)
875 return r;
876 }
877
878 r = sd_rtnl_message_new_link(*rtnl, &req, RTM_SETLINK, link->ifindex);
879 if (r < 0)
880 return r;
881
882 r = sr_iov_set_netlink_message(sr_iov, req);
883 if (r < 0)
884 return r;
885
886 r = sd_netlink_call(*rtnl, req, 0, NULL);
887 if (r < 0)
888 return r;
889
890 return 0;
891 }
892
893 static int link_apply_sr_iov_config(Link *link, sd_netlink **rtnl) {
894 SRIOV *sr_iov;
895 uint32_t n;
896 int r;
897
898 assert(link);
899 assert(link->config);
900 assert(link->device);
901
902 r = sr_iov_set_num_vfs(link->device, link->config->sr_iov_num_vfs, link->config->sr_iov_by_section);
903 if (r < 0)
904 log_link_warning_errno(link, r, "Failed to set the number of SR-IOV virtual functions, ignoring: %m");
905
906 if (ordered_hashmap_isempty(link->config->sr_iov_by_section))
907 return 0;
908
909 r = sr_iov_get_num_vfs(link->device, &n);
910 if (r < 0) {
911 log_link_warning_errno(link, r, "Failed to get the number of SR-IOV virtual functions, ignoring [SR-IOV] sections: %m");
912 return 0;
913 }
914 if (n == 0) {
915 log_link_warning(link, "No SR-IOV virtual function exists, ignoring [SR-IOV] sections: %m");
916 return 0;
917 }
918
919 ORDERED_HASHMAP_FOREACH(sr_iov, link->config->sr_iov_by_section) {
920 if (sr_iov->vf >= n) {
921 log_link_warning(link, "SR-IOV virtual function %"PRIu32" does not exist, ignoring.", sr_iov->vf);
922 continue;
923 }
924
925 r = sr_iov_configure(link, rtnl, sr_iov);
926 if (r < 0)
927 log_link_warning_errno(link, r,
928 "Failed to configure SR-IOV virtual function %"PRIu32", ignoring: %m",
929 sr_iov->vf);
930 }
931
932 return 0;
933 }
934
935 int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link) {
936 int r;
937
938 assert(ctx);
939 assert(rtnl);
940 assert(link);
941
942 if (!IN_SET(link->action, SD_DEVICE_ADD, SD_DEVICE_BIND, SD_DEVICE_MOVE)) {
943 log_link_debug(link, "Skipping to apply .link settings on '%s' uevent.",
944 device_action_to_string(link->action));
945
946 link->new_name = link->ifname;
947 return 0;
948 }
949
950 r = link_apply_ethtool_settings(link, &ctx->ethtool_fd);
951 if (r < 0)
952 return r;
953
954 r = link_apply_rtnl_settings(link, rtnl);
955 if (r < 0)
956 return r;
957
958 r = link_generate_new_name(link);
959 if (r < 0)
960 return r;
961
962 r = link_apply_alternative_names(link, rtnl);
963 if (r < 0)
964 return r;
965
966 r = link_apply_sr_iov_config(link, rtnl);
967 if (r < 0)
968 return r;
969
970 return 0;
971 }
972
973 int config_parse_ifalias(
974 const char *unit,
975 const char *filename,
976 unsigned line,
977 const char *section,
978 unsigned section_line,
979 const char *lvalue,
980 int ltype,
981 const char *rvalue,
982 void *data,
983 void *userdata) {
984
985 char **s = ASSERT_PTR(data);
986
987 assert(filename);
988 assert(lvalue);
989 assert(rvalue);
990
991 if (isempty(rvalue)) {
992 *s = mfree(*s);
993 return 0;
994 }
995
996 if (!ascii_is_valid(rvalue)) {
997 log_syntax(unit, LOG_WARNING, filename, line, 0,
998 "Interface alias is not ASCII clean, ignoring assignment: %s", rvalue);
999 return 0;
1000 }
1001
1002 if (strlen(rvalue) >= IFALIASZ) {
1003 log_syntax(unit, LOG_WARNING, filename, line, 0,
1004 "Interface alias is too long, ignoring assignment: %s", rvalue);
1005 return 0;
1006 }
1007
1008 return free_and_strdup_warn(s, rvalue);
1009 }
1010
1011 int config_parse_rx_tx_queues(
1012 const char *unit,
1013 const char *filename,
1014 unsigned line,
1015 const char *section,
1016 unsigned section_line,
1017 const char *lvalue,
1018 int ltype,
1019 const char *rvalue,
1020 void *data,
1021 void *userdata) {
1022
1023 uint32_t k, *v = data;
1024 int r;
1025
1026 if (isempty(rvalue)) {
1027 *v = 0;
1028 return 0;
1029 }
1030
1031 r = safe_atou32(rvalue, &k);
1032 if (r < 0) {
1033 log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s=, ignoring assignment: %s.", lvalue, rvalue);
1034 return 0;
1035 }
1036 if (k == 0 || k > 4096) {
1037 log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid %s=, ignoring assignment: %s.", lvalue, rvalue);
1038 return 0;
1039 }
1040
1041 *v = k;
1042 return 0;
1043 }
1044
1045 int config_parse_txqueuelen(
1046 const char *unit,
1047 const char *filename,
1048 unsigned line,
1049 const char *section,
1050 unsigned section_line,
1051 const char *lvalue,
1052 int ltype,
1053 const char *rvalue,
1054 void *data,
1055 void *userdata) {
1056
1057 uint32_t k, *v = data;
1058 int r;
1059
1060 if (isempty(rvalue)) {
1061 *v = UINT32_MAX;
1062 return 0;
1063 }
1064
1065 r = safe_atou32(rvalue, &k);
1066 if (r < 0) {
1067 log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s=, ignoring assignment: %s.", lvalue, rvalue);
1068 return 0;
1069 }
1070 if (k == UINT32_MAX) {
1071 log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid %s=, ignoring assignment: %s.", lvalue, rvalue);
1072 return 0;
1073 }
1074
1075 *v = k;
1076 return 0;
1077 }
1078
1079 int config_parse_wol_password(
1080 const char *unit,
1081 const char *filename,
1082 unsigned line,
1083 const char *section,
1084 unsigned section_line,
1085 const char *lvalue,
1086 int ltype,
1087 const char *rvalue,
1088 void *data,
1089 void *userdata) {
1090
1091 LinkConfig *config = ASSERT_PTR(userdata);
1092 int r;
1093
1094 assert(filename);
1095 assert(lvalue);
1096 assert(rvalue);
1097
1098 if (isempty(rvalue)) {
1099 config->wol_password = erase_and_free(config->wol_password);
1100 config->wol_password_file = mfree(config->wol_password_file);
1101 return 0;
1102 }
1103
1104 if (path_is_absolute(rvalue) && path_is_safe(rvalue)) {
1105 config->wol_password = erase_and_free(config->wol_password);
1106 return free_and_strdup_warn(&config->wol_password_file, rvalue);
1107 }
1108
1109 warn_file_is_world_accessible(filename, NULL, unit, line);
1110
1111 r = link_parse_wol_password(config, rvalue);
1112 if (r == -ENOMEM)
1113 return log_oom();
1114 if (r < 0) {
1115 log_syntax(unit, LOG_WARNING, filename, line, r,
1116 "Failed to parse %s=, ignoring assignment: %s.", lvalue, rvalue);
1117 return 0;
1118 }
1119
1120 config->wol_password_file = mfree(config->wol_password_file);
1121 return 0;
1122 }
1123
1124 static const char* const mac_address_policy_table[_MAC_ADDRESS_POLICY_MAX] = {
1125 [MAC_ADDRESS_POLICY_PERSISTENT] = "persistent",
1126 [MAC_ADDRESS_POLICY_RANDOM] = "random",
1127 [MAC_ADDRESS_POLICY_NONE] = "none",
1128 };
1129
1130 DEFINE_STRING_TABLE_LOOKUP(mac_address_policy, MACAddressPolicy);
1131 DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(
1132 config_parse_mac_address_policy,
1133 mac_address_policy,
1134 MACAddressPolicy,
1135 MAC_ADDRESS_POLICY_NONE,
1136 "Failed to parse MAC address policy");
1137
1138 DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy,
1139 _NAMEPOLICY_INVALID,
1140 "Failed to parse interface name policy");
1141
1142 DEFINE_CONFIG_PARSE_ENUMV(config_parse_alternative_names_policy, alternative_names_policy, NamePolicy,
1143 _NAMEPOLICY_INVALID,
1144 "Failed to parse alternative names policy");