1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <linux/netdevice.h>
4 #include <net/if_arp.h>
8 #include "sd-netlink.h"
10 #include "alloc-util.h"
11 #include "arphrd-util.h"
12 #include "condition.h"
13 #include "conf-files.h"
14 #include "conf-parser.h"
15 #include "creds-util.h"
16 #include "device-private.h"
17 #include "device-util.h"
19 #include "ether-addr-util.h"
20 #include "ethtool-util.h"
21 #include "extract-word.h"
25 #include "link-config.h"
27 #include "memory-util.h"
28 #include "net-condition.h"
29 #include "netif-naming-scheme.h"
30 #include "netif-sriov.h"
31 #include "netif-util.h"
32 #include "netlink-util.h"
33 #include "network-util.h"
34 #include "parse-util.h"
35 #include "path-util.h"
36 #include "proc-cmdline.h"
37 #include "random-util.h"
38 #include "socket-util.h"
39 #include "specifier.h"
40 #include "stat-util.h"
41 #include "string-table.h"
42 #include "string-util.h"
44 #include "udev-builtin.h"
47 static const Specifier link_specifier_table
[] = {
48 COMMON_SYSTEM_SPECIFIERS
,
49 COMMON_TMP_SPECIFIERS
,
53 struct LinkConfigContext
{
54 LIST_HEAD(LinkConfig
, configs
);
56 Hashmap
*stats_by_path
;
59 static LinkConfig
* link_config_free(LinkConfig
*config
) {
63 free(config
->filename
);
64 strv_free(config
->dropins
);
66 net_match_clear(&config
->match
);
67 condition_free_list(config
->conditions
);
69 free(config
->description
);
70 strv_free(config
->properties
);
71 strv_free(config
->import_properties
);
72 strv_free(config
->unset_properties
);
73 free(config
->name_policy
);
75 strv_free(config
->alternative_names
);
76 free(config
->alternative_names_policy
);
78 free(config
->wol_password_file
);
79 erase_and_free(config
->wol_password
);
80 cpu_set_done(&config
->rps_cpu_mask
);
82 ordered_hashmap_free(config
->sr_iov_by_section
);
87 DEFINE_TRIVIAL_CLEANUP_FUNC(LinkConfig
*, link_config_free
);
89 static void link_configs_free(LinkConfigContext
*ctx
) {
93 ctx
->stats_by_path
= hashmap_free(ctx
->stats_by_path
);
95 LIST_FOREACH(configs
, config
, ctx
->configs
)
96 link_config_free(config
);
99 LinkConfigContext
*link_config_ctx_free(LinkConfigContext
*ctx
) {
103 safe_close(ctx
->ethtool_fd
);
104 link_configs_free(ctx
);
108 int link_config_ctx_new(LinkConfigContext
**ret
) {
109 _cleanup_(link_config_ctx_freep
) LinkConfigContext
*ctx
= NULL
;
114 ctx
= new(LinkConfigContext
, 1);
118 *ctx
= (LinkConfigContext
) {
119 .ethtool_fd
= -EBADF
,
122 *ret
= TAKE_PTR(ctx
);
127 static int link_parse_wol_password(LinkConfig
*config
, const char *str
) {
128 _cleanup_(erase_and_freep
) uint8_t *p
= NULL
;
134 assert_cc(sizeof(struct ether_addr
) == SOPASS_MAX
);
136 p
= new(uint8_t, SOPASS_MAX
);
140 /* Reuse parse_ether_addr(), as their formats are equivalent. */
141 r
= parse_ether_addr(str
, (struct ether_addr
*) p
);
145 erase_and_free(config
->wol_password
);
146 config
->wol_password
= TAKE_PTR(p
);
150 static int link_read_wol_password_from_file(LinkConfig
*config
) {
151 _cleanup_(erase_and_freep
) char *password
= NULL
;
156 if (!config
->wol_password_file
)
159 r
= read_full_file_full(
160 AT_FDCWD
, config
->wol_password_file
, UINT64_MAX
, SIZE_MAX
,
161 READ_FULL_FILE_SECURE
| READ_FULL_FILE_WARN_WORLD_READABLE
| READ_FULL_FILE_CONNECT_SOCKET
,
162 NULL
, &password
, NULL
);
166 return link_parse_wol_password(config
, password
);
169 static int link_read_wol_password_from_cred(LinkConfig
*config
) {
170 _cleanup_free_
char *base
= NULL
, *cred_name
= NULL
;
171 _cleanup_(erase_and_freep
) char *password
= NULL
;
175 assert(config
->filename
);
177 if (config
->wol
== UINT32_MAX
)
178 return 0; /* WakeOnLan= is not specified. */
179 if (!FLAGS_SET(config
->wol
, WAKE_MAGICSECURE
))
180 return 0; /* secureon is not specified in WakeOnLan=. */
181 if (config
->wol_password
)
182 return 0; /* WakeOnLanPassword= is specified. */
183 if (config
->wol_password_file
)
184 return 0; /* a file name is specified in WakeOnLanPassword=, but failed to read it. */
186 r
= path_extract_filename(config
->filename
, &base
);
190 cred_name
= strjoin(base
, ".wol.password");
194 r
= read_credential(cred_name
, (void**) &password
, NULL
);
196 r
= read_credential("wol.password", (void**) &password
, NULL
);
200 return link_parse_wol_password(config
, password
);
203 static int link_adjust_wol_options(LinkConfig
*config
) {
208 r
= link_read_wol_password_from_file(config
);
212 log_warning_errno(r
, "Failed to read WakeOnLan password from %s, ignoring: %m", config
->wol_password_file
);
214 r
= link_read_wol_password_from_cred(config
);
218 log_warning_errno(r
, "Failed to read WakeOnLan password from credential, ignoring: %m");
220 if (config
->wol
!= UINT32_MAX
&& config
->wol_password
)
221 /* Enable WAKE_MAGICSECURE flag when WakeOnLanPassword=. Note that when
222 * WakeOnLanPassword= is set without WakeOnLan=, then ethtool_set_wol() enables
223 * WAKE_MAGICSECURE flag and other flags are not changed. */
224 config
->wol
|= WAKE_MAGICSECURE
;
229 int link_load_one(LinkConfigContext
*ctx
, const char *filename
) {
230 _cleanup_(link_config_freep
) LinkConfig
*config
= NULL
;
231 _cleanup_hashmap_free_ Hashmap
*stats_by_path
= NULL
;
232 _cleanup_free_
char *name
= NULL
, *file_basename
= NULL
;
233 const char *dropin_dirname
;
239 r
= null_or_empty_path(filename
);
241 return log_warning_errno(r
, "Failed to check if \"%s\" is empty: %m", filename
);
243 log_debug("Skipping empty file: %s", filename
);
247 name
= strdup(filename
);
251 config
= new(LinkConfig
, 1);
255 *config
= (LinkConfig
) {
256 .filename
= TAKE_PTR(name
),
257 .mac_address_policy
= MAC_ADDRESS_POLICY_NONE
,
258 .wol
= UINT32_MAX
, /* UINT32_MAX means do not change WOL setting. */
259 .duplex
= _DUP_INVALID
,
260 .port
= _NET_DEV_PORT_INVALID
,
261 .autonegotiation
= -1,
262 .rx_flow_control
= -1,
263 .tx_flow_control
= -1,
264 .autoneg_flow_control
= -1,
265 .txqueuelen
= UINT32_MAX
,
266 .coalesce
.use_adaptive_rx_coalesce
= -1,
267 .coalesce
.use_adaptive_tx_coalesce
= -1,
268 .mdi
= ETH_TP_MDI_INVALID
,
269 .sr_iov_num_vfs
= UINT32_MAX
,
271 .eee_tx_lpi_enabled
= -1,
272 .eee_tx_lpi_timer_usec
= USEC_INFINITY
,
275 FOREACH_ELEMENT(feature
, config
->features
)
278 r
= path_extract_filename(filename
, &file_basename
);
280 return log_error_errno(r
, "Failed to extract file name of '%s': %m", filename
);
282 dropin_dirname
= strjoina(file_basename
, ".d");
283 r
= config_parse_many(
284 STRV_MAKE_CONST(filename
),
291 "EnergyEfficientEthernet\0",
292 config_item_perf_lookup
, link_config_gperf_lookup
,
293 CONFIG_PARSE_WARN
, config
, &stats_by_path
,
296 return r
; /* config_parse_many() logs internally. */
298 if (ctx
->stats_by_path
) {
299 r
= hashmap_move(ctx
->stats_by_path
, stats_by_path
);
301 log_warning_errno(r
, "Failed to save stats of '%s' and its drop-in configs, ignoring: %m", filename
);
303 ctx
->stats_by_path
= TAKE_PTR(stats_by_path
);
305 if (net_match_is_empty(&config
->match
) && !config
->conditions
) {
306 log_warning("%s: No valid settings found in the [Match] section, ignoring file. "
307 "To match all interfaces, add OriginalName=* in the [Match] section.",
312 if (!condition_test_list(config
->conditions
, environ
, NULL
, NULL
, NULL
)) {
313 log_debug("%s: Conditions do not match the system environment, skipping.", filename
);
317 if (IN_SET(config
->mac_address_policy
, MAC_ADDRESS_POLICY_PERSISTENT
, MAC_ADDRESS_POLICY_RANDOM
) &&
318 config
->hw_addr
.length
> 0)
319 log_warning("%s: MACAddress= in [Link] section will be ignored when MACAddressPolicy= "
320 "is set to \"persistent\" or \"random\".",
323 r
= link_adjust_wol_options(config
);
325 return r
; /* link_adjust_wol_options() logs internally. */
327 r
= sr_iov_drop_invalid_sections(config
->sr_iov_num_vfs
, config
->sr_iov_by_section
);
329 return r
; /* sr_iov_drop_invalid_sections() logs internally. */
331 log_debug("Parsed configuration file \"%s\"", filename
);
333 LIST_PREPEND(configs
, ctx
->configs
, TAKE_PTR(config
));
337 int link_config_load(LinkConfigContext
*ctx
) {
338 _cleanup_strv_free_
char **files
= NULL
;
343 link_configs_free(ctx
);
345 r
= conf_files_list_strv(&files
, ".link", NULL
, 0, NETWORK_DIRS
);
347 return log_error_errno(r
, "failed to enumerate link files: %m");
349 STRV_FOREACH_BACKWARDS(f
, files
)
350 (void) link_load_one(ctx
, *f
);
355 bool link_config_should_reload(LinkConfigContext
*ctx
) {
356 _cleanup_hashmap_free_ Hashmap
*stats_by_path
= NULL
;
361 r
= config_get_stats_by_path(".link", NULL
, 0, NETWORK_DIRS
, /* check_dropins = */ true, &stats_by_path
);
363 log_warning_errno(r
, "Failed to get stats of .link files, ignoring: %m");
367 return !stats_by_path_equal(ctx
->stats_by_path
, stats_by_path
);
370 Link
* link_free(Link
*link
) {
374 udev_event_unref(link
->event
);
379 int link_new(LinkConfigContext
*ctx
, UdevEvent
*event
, Link
**ret
) {
380 sd_device
*dev
= ASSERT_PTR(ASSERT_PTR(event
)->dev
);
381 _cleanup_(link_freep
) Link
*link
= NULL
;
393 .event
= udev_event_ref(event
),
396 r
= device_get_ifname(dev
, &link
->ifname
);
400 r
= sd_device_get_ifindex(dev
, &link
->ifindex
);
404 r
= sd_device_get_action(dev
, &link
->action
);
408 r
= device_get_sysattr_unsigned(dev
, "name_assign_type", &link
->name_assign_type
);
410 log_link_debug_errno(link
, r
, "Failed to get \"name_assign_type\" attribute, ignoring: %m");
412 log_link_debug(link
, "Device has name_assign_type attribute: %u", link
->name_assign_type
);
414 r
= device_get_sysattr_unsigned(dev
, "addr_assign_type", &link
->addr_assign_type
);
416 log_link_debug_errno(link
, r
, "Failed to get \"addr_assign_type\" attribute, ignoring: %m");
418 log_link_debug(link
, "Device has addr_assign_type attribute: %u", link
->addr_assign_type
);
420 r
= rtnl_get_link_info(&event
->rtnl
, link
->ifindex
, &link
->iftype
, &link
->flags
,
421 &link
->kind
, &link
->hw_addr
, &link
->permanent_hw_addr
);
425 if (link
->hw_addr
.length
> 0 && link
->permanent_hw_addr
.length
== 0) {
426 r
= ethtool_get_permanent_hw_addr(&ctx
->ethtool_fd
, link
->ifname
, &link
->permanent_hw_addr
);
428 log_link_debug_errno(link
, r
, "Failed to get permanent hardware address, ignoring: %m");
431 r
= sd_device_get_property_value(dev
, "ID_NET_DRIVER", &link
->driver
);
432 if (r
< 0 && r
!= -ENOENT
)
433 log_link_debug_errno(link
, r
, "Failed to get driver, ignoring: %m");
435 *ret
= TAKE_PTR(link
);
439 int link_get_config(LinkConfigContext
*ctx
, Link
*link
) {
445 /* Do not configure loopback interfaces by .link files. */
446 if (link
->flags
& IFF_LOOPBACK
)
449 LIST_FOREACH(configs
, config
, ctx
->configs
) {
450 r
= net_match_config(
454 &link
->permanent_hw_addr
,
459 /* alternative_names = */ NULL
,
460 /* wlan_iftype = */ 0,
468 if (config
->match
.ifname
&& !strv_contains(config
->match
.ifname
, "*") && link
->name_assign_type
== NET_NAME_ENUM
)
469 log_link_warning(link
, "Config file %s is applied to device based on potentially unpredictable interface name.",
472 log_link_debug(link
, "Config file %s is applied", config
->filename
);
474 link
->config
= config
;
481 static int link_apply_ethtool_settings(Link
*link
, int *ethtool_fd
) {
482 LinkConfig
*config
= ASSERT_PTR(ASSERT_PTR(link
)->config
);
483 const char *name
= ASSERT_PTR(link
->ifname
);
489 if (link
->event
->event_mode
!= EVENT_UDEV_WORKER
) {
490 log_link_debug(link
, "Running in test mode, skipping application of ethtool settings.");
494 r
= ethtool_set_glinksettings(ethtool_fd
, name
,
495 config
->autonegotiation
, config
->advertise
,
496 config
->speed
, config
->duplex
, config
->port
, config
->mdi
);
498 if (config
->autonegotiation
>= 0)
499 log_link_warning_errno(link
, r
, "Could not %s auto negotiation, ignoring: %m",
500 enable_disable(config
->autonegotiation
));
502 if (!eqzero(config
->advertise
))
503 log_link_warning_errno(link
, r
, "Could not set advertise mode, ignoring: %m");
505 if (config
->speed
> 0)
506 log_link_warning_errno(link
, r
, "Could not set speed to %"PRIu64
"Mbps, ignoring: %m",
507 DIV_ROUND_UP(config
->speed
, 1000000));
509 if (config
->duplex
>= 0)
510 log_link_warning_errno(link
, r
, "Could not set duplex to %s, ignoring: %m",
511 duplex_to_string(config
->duplex
));
513 if (config
->port
>= 0)
514 log_link_warning_errno(link
, r
, "Could not set port to '%s', ignoring: %m",
515 port_to_string(config
->port
));
517 if (config
->mdi
!= ETH_TP_MDI_INVALID
)
518 log_link_warning_errno(link
, r
, "Could not set MDI-X to '%s', ignoring: %m",
519 mdi_to_string(config
->mdi
));
522 r
= ethtool_set_wol(ethtool_fd
, name
, config
->wol
, config
->wol_password
);
524 _cleanup_free_
char *str
= NULL
;
526 (void) wol_options_to_string_alloc(config
->wol
, &str
);
527 log_link_warning_errno(link
, r
, "Could not set WakeOnLan%s%s, ignoring: %m",
528 isempty(str
) ? "" : " to ", strempty(str
));
531 r
= ethtool_set_features(ethtool_fd
, name
, config
->features
);
533 log_link_warning_errno(link
, r
, "Could not set offload features, ignoring: %m");
535 r
= ethtool_set_channels(ethtool_fd
, name
, &config
->channels
);
537 log_link_warning_errno(link
, r
, "Could not set channels, ignoring: %m");
539 r
= ethtool_set_nic_buffer_size(ethtool_fd
, name
, &config
->ring
);
541 log_link_warning_errno(link
, r
, "Could not set ring buffer, ignoring: %m");
543 r
= ethtool_set_flow_control(ethtool_fd
, name
, config
->rx_flow_control
, config
->tx_flow_control
, config
->autoneg_flow_control
);
545 log_link_warning_errno(link
, r
, "Could not set flow control, ignoring: %m");
547 r
= ethtool_set_nic_coalesce_settings(ethtool_fd
, name
, &config
->coalesce
);
549 log_link_warning_errno(link
, r
, "Could not set coalesce settings, ignoring: %m");
551 r
= ethtool_set_eee_settings(ethtool_fd
, name
, config
->eee_enabled
, config
->eee_tx_lpi_enabled
, config
->eee_tx_lpi_timer_usec
, config
->eee_advertise
[0]);
553 log_link_warning_errno(link
, r
, "Could not set energy efficient ethernet settings, ignoring: %m");
558 static bool hw_addr_is_valid(Link
*link
, const struct hw_addr_data
*hw_addr
) {
562 switch (link
->iftype
) {
564 /* Refuse all zero and all 0xFF. */
565 assert(hw_addr
->length
== ETH_ALEN
);
566 return !ether_addr_is_null(&hw_addr
->ether
) && !ether_addr_is_broadcast(&hw_addr
->ether
);
568 case ARPHRD_INFINIBAND
:
569 /* The last 8 bytes cannot be zero. */
570 assert(hw_addr
->length
== INFINIBAND_ALEN
);
571 return !memeqzero(hw_addr
->bytes
+ INFINIBAND_ALEN
- 8, 8);
574 assert_not_reached();
578 static int link_generate_new_hw_addr(Link
*link
, struct hw_addr_data
*ret
) {
579 struct hw_addr_data hw_addr
= HW_ADDR_NULL
;
580 bool is_static
= false;
586 assert(link
->config
);
588 assert(link
->event
->dev
);
591 if (link
->hw_addr
.length
== 0)
594 if (link
->config
->mac_address_policy
== MAC_ADDRESS_POLICY_NONE
) {
595 log_link_debug(link
, "Using static MAC address.");
596 hw_addr
= link
->config
->hw_addr
;
601 if (!IN_SET(link
->iftype
, ARPHRD_ETHER
, ARPHRD_INFINIBAND
))
604 switch (link
->addr_assign_type
) {
606 log_link_debug(link
, "MAC address on the device already set by userspace.");
608 case NET_ADDR_STOLEN
:
609 log_link_debug(link
, "MAC address on the device already set based on another device.");
611 case NET_ADDR_RANDOM
:
615 log_link_warning(link
, "Unknown addr_assign_type %u, ignoring", link
->addr_assign_type
);
619 if ((link
->config
->mac_address_policy
== MAC_ADDRESS_POLICY_RANDOM
) == (link
->addr_assign_type
== NET_ADDR_RANDOM
)) {
620 log_link_debug(link
, "MAC address on the device already matches policy \"%s\".",
621 mac_address_policy_to_string(link
->config
->mac_address_policy
));
625 hw_addr
= (struct hw_addr_data
) {
626 .length
= arphrd_to_hw_addr_len(link
->iftype
),
629 switch (link
->iftype
) {
632 len
= hw_addr
.length
;
634 case ARPHRD_INFINIBAND
:
635 p
= hw_addr
.bytes
+ INFINIBAND_ALEN
- 8;
639 assert_not_reached();
642 if (link
->config
->mac_address_policy
== MAC_ADDRESS_POLICY_RANDOM
)
643 /* We require genuine randomness here, since we want to make sure we won't collide with other
644 * systems booting up at the very same time. */
646 random_bytes(p
, len
);
647 if (hw_addr_is_valid(link
, &hw_addr
))
654 r
= net_get_unique_predictable_data(link
->event
->dev
,
655 naming_scheme_has(NAMING_STABLE_VIRTUAL_MACS
),
658 return log_link_warning_errno(link
, r
, "Could not generate persistent MAC address: %m");
660 assert(len
<= sizeof(result
));
661 memcpy(p
, &result
, len
);
662 if (!hw_addr_is_valid(link
, &hw_addr
))
663 return log_link_warning_errno(link
, SYNTHETIC_ERRNO(EINVAL
),
664 "Could not generate valid persistent MAC address: %m");
669 r
= net_verify_hardware_address(link
->ifname
, is_static
, link
->iftype
, &link
->hw_addr
, &hw_addr
);
673 if (hw_addr_equal(&link
->hw_addr
, &hw_addr
)) {
678 if (hw_addr
.length
> 0)
679 log_link_debug(link
, "Applying %s MAC address: %s",
680 link
->config
->mac_address_policy
== MAC_ADDRESS_POLICY_NONE
? "static" :
681 mac_address_policy_to_string(link
->config
->mac_address_policy
),
682 HW_ADDR_TO_STR(&hw_addr
));
688 static int link_apply_rtnl_settings(Link
*link
) {
689 struct hw_addr_data hw_addr
= {};
690 LinkConfig
*config
= ASSERT_PTR(ASSERT_PTR(link
)->config
);
695 if (link
->event
->event_mode
!= EVENT_UDEV_WORKER
) {
696 log_link_debug(link
, "Running in test mode, skipping application of rtnl settings.");
700 (void) link_generate_new_hw_addr(link
, &hw_addr
);
702 r
= rtnl_set_link_properties(&link
->event
->rtnl
, link
->ifindex
, config
->alias
, &hw_addr
,
703 config
->txqueues
, config
->rxqueues
, config
->txqueuelen
,
704 config
->mtu
, config
->gso_max_size
, config
->gso_max_segments
);
706 log_link_warning_errno(link
, r
,
707 "Could not set Alias=, MACAddress=/MACAddressPolicy=, "
708 "TransmitQueues=, ReceiveQueues=, TransmitQueueLength=, MTUBytes=, "
709 "GenericSegmentOffloadMaxBytes= or GenericSegmentOffloadMaxSegments=, "
715 static bool enable_name_policy(void) {
716 static int cached
= -1;
723 r
= proc_cmdline_get_bool("net.ifnames", /* flags = */ 0, &b
);
725 log_warning_errno(r
, "Failed to parse net.ifnames= kernel command line option, ignoring: %m");
727 return (cached
= true);
730 log_info("Network interface NamePolicy= disabled on kernel command line.");
735 static int link_generate_new_name(Link
*link
) {
736 LinkConfig
*config
= ASSERT_PTR(ASSERT_PTR(link
)->config
);;
737 sd_device
*device
= ASSERT_PTR(ASSERT_PTR(link
->event
)->dev
);
739 if (link
->action
!= SD_DEVICE_ADD
) {
740 log_link_debug(link
, "Not applying Name= and NamePolicy= on '%s' uevent.",
741 device_action_to_string(link
->action
));
745 if (IN_SET(link
->name_assign_type
, NET_NAME_USER
, NET_NAME_RENAMED
) &&
746 !naming_scheme_has(NAMING_ALLOW_RERENAMES
)) {
747 log_link_debug(link
, "Device already has a name given by userspace, not renaming.");
751 if (enable_name_policy() && config
->name_policy
)
752 for (NamePolicy
*policy
= config
->name_policy
; *policy
!= _NAMEPOLICY_INVALID
; policy
++) {
753 const char *new_name
= NULL
;
756 case NAMEPOLICY_KERNEL
:
757 if (link
->name_assign_type
!= NET_NAME_PREDICTABLE
)
760 /* The kernel claims to have given a predictable name, keep it. */
761 log_link_debug(link
, "Policy *%s*: keeping predictable kernel name",
762 name_policy_to_string(*policy
));
764 case NAMEPOLICY_KEEP
:
765 if (!IN_SET(link
->name_assign_type
, NET_NAME_USER
, NET_NAME_RENAMED
))
768 log_link_debug(link
, "Policy *%s*: keeping existing userspace name",
769 name_policy_to_string(*policy
));
771 case NAMEPOLICY_DATABASE
:
772 (void) sd_device_get_property_value(device
, "ID_NET_NAME_FROM_DATABASE", &new_name
);
774 case NAMEPOLICY_ONBOARD
:
775 (void) sd_device_get_property_value(device
, "ID_NET_NAME_ONBOARD", &new_name
);
777 case NAMEPOLICY_SLOT
:
778 (void) sd_device_get_property_value(device
, "ID_NET_NAME_SLOT", &new_name
);
780 case NAMEPOLICY_PATH
:
781 (void) sd_device_get_property_value(device
, "ID_NET_NAME_PATH", &new_name
);
784 (void) sd_device_get_property_value(device
, "ID_NET_NAME_MAC", &new_name
);
787 assert_not_reached();
789 if (ifname_valid(new_name
)) {
790 log_link_debug(link
, "Policy *%s* yields \"%s\".", name_policy_to_string(*policy
), new_name
);
791 link
->new_name
= new_name
;
796 if (link
->config
->name
) {
797 log_link_debug(link
, "Policies didn't yield a name, using specified Name=%s.", link
->config
->name
);
798 link
->new_name
= link
->config
->name
;
802 log_link_debug(link
, "Policies didn't yield a name and Name= is not given, not renaming.");
804 if (!naming_scheme_has(NAMING_USE_INTERFACE_PROPERTY
))
805 return sd_device_get_sysname(device
, &link
->new_name
);
807 link
->new_name
= link
->ifname
;
811 static int link_generate_alternative_names(Link
*link
) {
812 _cleanup_strv_free_
char **altnames
= NULL
;
813 LinkConfig
*config
= ASSERT_PTR(ASSERT_PTR(link
)->config
);
814 sd_device
*device
= ASSERT_PTR(ASSERT_PTR(link
->event
)->dev
);
817 assert(!ASSERT_PTR(link
->event
)->altnames
);
819 if (link
->action
!= SD_DEVICE_ADD
) {
820 log_link_debug(link
, "Not applying AlternativeNames= and AlternativeNamesPolicy= on '%s' uevent.",
821 device_action_to_string(link
->action
));
825 if (config
->alternative_names
) {
826 altnames
= strv_copy(config
->alternative_names
);
831 if (config
->alternative_names_policy
)
832 for (NamePolicy
*p
= config
->alternative_names_policy
; *p
!= _NAMEPOLICY_INVALID
; p
++) {
833 const char *n
= NULL
;
836 case NAMEPOLICY_DATABASE
:
837 (void) sd_device_get_property_value(device
, "ID_NET_NAME_FROM_DATABASE", &n
);
839 case NAMEPOLICY_ONBOARD
:
840 (void) sd_device_get_property_value(device
, "ID_NET_NAME_ONBOARD", &n
);
842 case NAMEPOLICY_SLOT
:
843 (void) sd_device_get_property_value(device
, "ID_NET_NAME_SLOT", &n
);
845 case NAMEPOLICY_PATH
:
846 (void) sd_device_get_property_value(device
, "ID_NET_NAME_PATH", &n
);
849 (void) sd_device_get_property_value(device
, "ID_NET_NAME_MAC", &n
);
852 assert_not_reached();
854 if (ifname_valid_full(n
, IFNAME_VALID_ALTERNATIVE
)) {
855 r
= strv_extend(&altnames
, n
);
861 link
->event
->altnames
= TAKE_PTR(altnames
);
865 static int sr_iov_configure(Link
*link
, sd_netlink
**rtnl
, SRIOV
*sr_iov
, SRIOVAttribute attr
) {
870 assert(link
->ifindex
> 0);
872 if (!sr_iov_has_config(sr_iov
, attr
))
876 r
= sd_netlink_open(rtnl
);
881 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
;
882 r
= sd_rtnl_message_new_link(*rtnl
, &req
, RTM_SETLINK
, link
->ifindex
);
886 r
= sr_iov_set_netlink_message(sr_iov
, attr
, req
);
890 return sd_netlink_call(*rtnl
, req
, 0, NULL
);
893 static int link_apply_sr_iov_config(Link
*link
) {
899 assert(link
->config
);
900 assert(ASSERT_PTR(link
->event
)->dev
);
902 if (link
->event
->event_mode
!= EVENT_UDEV_WORKER
) {
903 log_link_debug(link
, "Running in test mode, skipping application of SR-IOV settings.");
907 r
= sr_iov_set_num_vfs(link
->event
->dev
, link
->config
->sr_iov_num_vfs
, link
->config
->sr_iov_by_section
);
909 log_link_warning_errno(link
, r
, "Failed to set the number of SR-IOV virtual functions, ignoring: %m");
911 if (ordered_hashmap_isempty(link
->config
->sr_iov_by_section
))
914 r
= sr_iov_get_num_vfs(link
->event
->dev
, &n
);
916 log_link_warning_errno(link
, r
, "Failed to get the number of SR-IOV virtual functions, ignoring all [SR-IOV] sections: %m");
920 log_link_warning(link
, "No SR-IOV virtual function exists, ignoring all [SR-IOV] sections: %m");
924 ORDERED_HASHMAP_FOREACH(sr_iov
, link
->config
->sr_iov_by_section
) {
925 if (sr_iov
->vf
>= n
) {
926 log_link_warning(link
, "SR-IOV virtual function %"PRIu32
" does not exist, ignoring [SR-IOV] section for the virtual function.", sr_iov
->vf
);
930 for (SRIOVAttribute attr
= 0; attr
< _SR_IOV_ATTRIBUTE_MAX
; attr
++) {
931 r
= sr_iov_configure(link
, &link
->event
->rtnl
, sr_iov
, attr
);
933 log_link_warning_errno(link
, r
,
934 "Failed to set up %s for SR-IOV virtual function %"PRIu32
", ignoring: %m",
935 sr_iov_attribute_to_string(attr
), sr_iov
->vf
);
942 static int link_apply_rps_cpu_mask(Link
*link
) {
943 _cleanup_free_
char *mask_str
= NULL
;
947 config
= ASSERT_PTR(ASSERT_PTR(link
)->config
);
948 assert(ASSERT_PTR(link
->event
)->dev
);
950 if (link
->event
->event_mode
!= EVENT_UDEV_WORKER
) {
951 log_link_debug(link
, "Running in test mode, skipping application of RPS setting.");
955 /* Skip if the config is not specified. */
956 if (!config
->rps_cpu_mask
.set
)
959 mask_str
= cpu_set_to_mask_string(&config
->rps_cpu_mask
);
963 log_link_debug(link
, "Applying RPS CPU mask: %s", mask_str
);
965 /* Currently, this will set CPU mask to all rx queue of matched device. */
966 FOREACH_DEVICE_SYSATTR(link
->event
->dev
, attr
) {
969 c
= path_startswith(attr
, "queues/");
973 c
= startswith(c
, "rx-");
977 c
+= strcspn(c
, "/");
979 if (!path_equal(c
, "/rps_cpus"))
982 r
= sd_device_set_sysattr_value(link
->event
->dev
, attr
, mask_str
);
984 log_link_warning_errno(link
, r
, "Failed to write %s sysfs attribute, ignoring: %m", attr
);
990 static int link_apply_udev_properties(Link
*link
) {
991 LinkConfig
*config
= ASSERT_PTR(ASSERT_PTR(link
)->config
);
992 UdevEvent
*event
= ASSERT_PTR(link
->event
);
994 /* 1. apply ImportProperty=. */
995 STRV_FOREACH(p
, config
->import_properties
)
996 (void) udev_builtin_import_property(event
, *p
);
998 /* 2. apply Property=. */
999 STRV_FOREACH(p
, config
->properties
) {
1000 _cleanup_free_
char *key
= NULL
;
1003 eq
= strchr(*p
, '=');
1007 key
= strndup(*p
, eq
- *p
);
1011 (void) udev_builtin_add_property(event
, key
, eq
+ 1);
1014 /* 3. apply UnsetProperty=. */
1015 STRV_FOREACH(p
, config
->unset_properties
)
1016 (void) udev_builtin_add_property(event
, *p
, NULL
);
1018 /* 4. set the default properties. */
1019 (void) udev_builtin_add_property(event
, "ID_NET_LINK_FILE", config
->filename
);
1021 _cleanup_free_
char *joined
= NULL
;
1022 STRV_FOREACH(d
, config
->dropins
) {
1023 _cleanup_free_
char *escaped
= NULL
;
1025 escaped
= xescape(*d
, ":");
1029 if (!strextend_with_separator(&joined
, ":", escaped
))
1033 (void) udev_builtin_add_property(event
, "ID_NET_LINK_FILE_DROPINS", joined
);
1036 (void) udev_builtin_add_property(event
, "ID_NET_NAME", link
->new_name
);
1041 int link_apply_config(LinkConfigContext
*ctx
, Link
*link
) {
1047 r
= link_apply_ethtool_settings(link
, &ctx
->ethtool_fd
);
1051 r
= link_apply_rtnl_settings(link
);
1055 r
= link_generate_new_name(link
);
1059 r
= link_generate_alternative_names(link
);
1063 r
= link_apply_sr_iov_config(link
);
1067 r
= link_apply_rps_cpu_mask(link
);
1071 return link_apply_udev_properties(link
);
1074 int config_parse_udev_property(
1076 const char *filename
,
1078 const char *section
,
1079 unsigned section_line
,
1086 char ***properties
= ASSERT_PTR(data
);
1093 if (isempty(rvalue
)) {
1094 /* Empty assignment resets the list */
1095 *properties
= strv_free(*properties
);
1099 for (const char *p
= rvalue
;; ) {
1100 _cleanup_free_
char *word
= NULL
, *resolved
= NULL
, *key
= NULL
;
1103 r
= extract_first_word(&p
, &word
, NULL
, EXTRACT_CUNESCAPE
|EXTRACT_UNQUOTE
);
1107 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1108 "Invalid syntax, ignoring assignment: %s", rvalue
);
1114 r
= specifier_printf(word
, SIZE_MAX
, link_specifier_table
, NULL
, NULL
, &resolved
);
1116 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1117 "Failed to resolve specifiers in %s, ignoring assignment: %m", word
);
1121 if (!udev_property_assignment_is_valid(resolved
)) {
1122 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1123 "Invalid udev property, ignoring assignment: %s", word
);
1127 assert_se(eq
= strchr(resolved
, '='));
1128 key
= strndup(resolved
, eq
- resolved
);
1132 if (!device_property_can_set(key
)) {
1133 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1134 "Invalid udev property name '%s', ignoring assignment: %s", key
, resolved
);
1138 r
= strv_env_replace_consume(properties
, TAKE_PTR(resolved
));
1140 return log_error_errno(r
, "Failed to update properties: %m");
1144 int config_parse_udev_property_name(
1146 const char *filename
,
1148 const char *section
,
1149 unsigned section_line
,
1156 char ***properties
= ASSERT_PTR(data
);
1163 if (isempty(rvalue
)) {
1164 /* Empty assignment resets the list */
1165 *properties
= strv_free(*properties
);
1169 for (const char *p
= rvalue
;; ) {
1170 _cleanup_free_
char *word
= NULL
, *resolved
= NULL
;
1172 r
= extract_first_word(&p
, &word
, NULL
, EXTRACT_CUNESCAPE
|EXTRACT_UNQUOTE
);
1176 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1177 "Invalid syntax, ignoring assignment: %s", rvalue
);
1183 r
= specifier_printf(word
, SIZE_MAX
, link_specifier_table
, NULL
, NULL
, &resolved
);
1185 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1186 "Failed to resolve specifiers in %s, ignoring assignment: %m", word
);
1190 if (!udev_property_name_is_valid(resolved
)) {
1191 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1192 "Invalid udev property name, ignoring assignment: %s", resolved
);
1196 if (!device_property_can_set(resolved
)) {
1197 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1198 "Invalid udev property name, ignoring assignment: %s", resolved
);
1202 r
= strv_consume(properties
, TAKE_PTR(resolved
));
1204 return log_error_errno(r
, "Failed to update properties: %m");
1208 int config_parse_ifalias(
1210 const char *filename
,
1212 const char *section
,
1213 unsigned section_line
,
1220 char **s
= ASSERT_PTR(data
);
1226 if (isempty(rvalue
)) {
1231 if (!ascii_is_valid(rvalue
)) {
1232 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1233 "Interface alias is not ASCII clean, ignoring assignment: %s", rvalue
);
1237 if (strlen(rvalue
) >= IFALIASZ
) {
1238 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
1239 "Interface alias is too long, ignoring assignment: %s", rvalue
);
1243 return free_and_strdup_warn(s
, rvalue
);
1246 int config_parse_rx_tx_queues(
1248 const char *filename
,
1250 const char *section
,
1251 unsigned section_line
,
1258 uint32_t k
, *v
= data
;
1261 if (isempty(rvalue
)) {
1266 r
= safe_atou32(rvalue
, &k
);
1268 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
, "Failed to parse %s=, ignoring assignment: %s.", lvalue
, rvalue
);
1271 if (k
== 0 || k
> 4096) {
1272 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0, "Invalid %s=, ignoring assignment: %s.", lvalue
, rvalue
);
1280 int config_parse_txqueuelen(
1282 const char *filename
,
1284 const char *section
,
1285 unsigned section_line
,
1292 uint32_t k
, *v
= data
;
1295 if (isempty(rvalue
)) {
1300 r
= safe_atou32(rvalue
, &k
);
1302 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
, "Failed to parse %s=, ignoring assignment: %s.", lvalue
, rvalue
);
1305 if (k
== UINT32_MAX
) {
1306 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0, "Invalid %s=, ignoring assignment: %s.", lvalue
, rvalue
);
1314 int config_parse_wol_password(
1316 const char *filename
,
1318 const char *section
,
1319 unsigned section_line
,
1326 LinkConfig
*config
= ASSERT_PTR(userdata
);
1333 if (isempty(rvalue
)) {
1334 config
->wol_password
= erase_and_free(config
->wol_password
);
1335 config
->wol_password_file
= mfree(config
->wol_password_file
);
1339 if (path_is_absolute(rvalue
) && path_is_safe(rvalue
)) {
1340 config
->wol_password
= erase_and_free(config
->wol_password
);
1341 return free_and_strdup_warn(&config
->wol_password_file
, rvalue
);
1344 warn_file_is_world_accessible(filename
, NULL
, unit
, line
);
1346 r
= link_parse_wol_password(config
, rvalue
);
1350 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1351 "Failed to parse %s=, ignoring assignment: %s.", lvalue
, rvalue
);
1355 config
->wol_password_file
= mfree(config
->wol_password_file
);
1359 int config_parse_rps_cpu_mask(
1361 const char *filename
,
1363 const char *section
,
1364 unsigned section_line
,
1371 CPUSet
*mask
= ASSERT_PTR(data
);
1376 if (streq(rvalue
, "disable")) {
1377 _cleanup_(cpu_set_done
) CPUSet c
= {};
1379 r
= cpu_set_realloc(&c
, 1);
1383 return cpu_set_done_and_replace(*mask
, c
);
1386 if (streq(rvalue
, "all")) {
1387 _cleanup_(cpu_set_done
) CPUSet c
= {};
1389 r
= cpu_set_add_all(&c
);
1391 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1392 "Failed to create CPU affinity mask representing \"all\" cpus, ignoring: %m");
1396 return cpu_set_done_and_replace(*mask
, c
);
1399 return config_parse_cpu_set(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, data
, userdata
);
1402 static const char* const mac_address_policy_table
[_MAC_ADDRESS_POLICY_MAX
] = {
1403 [MAC_ADDRESS_POLICY_PERSISTENT
] = "persistent",
1404 [MAC_ADDRESS_POLICY_RANDOM
] = "random",
1405 [MAC_ADDRESS_POLICY_NONE
] = "none",
1408 DEFINE_STRING_TABLE_LOOKUP(mac_address_policy
, MACAddressPolicy
);
1409 DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(
1410 config_parse_mac_address_policy
,
1413 MAC_ADDRESS_POLICY_NONE
);
1415 DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy
, name_policy
, NamePolicy
,
1416 _NAMEPOLICY_INVALID
);
1418 DEFINE_CONFIG_PARSE_ENUMV(config_parse_alternative_names_policy
, alternative_names_policy
, NamePolicy
,
1419 _NAMEPOLICY_INVALID
);