1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <linux/netdevice.h>
4 #include <netinet/ether.h>
8 #include "sd-netlink.h"
10 #include "alloc-util.h"
11 #include "arphrd-util.h"
12 #include "conf-files.h"
13 #include "conf-parser.h"
14 #include "creds-util.h"
16 #include "device-private.h"
17 #include "device-util.h"
18 #include "ethtool-util.h"
21 #include "link-config.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"
39 struct LinkConfigContext
{
40 LIST_HEAD(LinkConfig
, configs
);
42 bool enable_name_policy
;
43 usec_t network_dirs_ts_usec
;
46 static LinkConfig
* link_config_free(LinkConfig
*config
) {
50 free(config
->filename
);
52 net_match_clear(&config
->match
);
53 condition_free_list(config
->conditions
);
55 free(config
->description
);
56 free(config
->name_policy
);
58 strv_free(config
->alternative_names
);
59 free(config
->alternative_names_policy
);
61 free(config
->wol_password_file
);
62 erase_and_free(config
->wol_password
);
64 ordered_hashmap_free_with_destructor(config
->sr_iov_by_section
, sr_iov_free
);
69 DEFINE_TRIVIAL_CLEANUP_FUNC(LinkConfig
*, link_config_free
);
71 static void link_configs_free(LinkConfigContext
*ctx
) {
75 LIST_FOREACH(configs
, config
, ctx
->configs
)
76 link_config_free(config
);
79 LinkConfigContext
*link_config_ctx_free(LinkConfigContext
*ctx
) {
83 safe_close(ctx
->ethtool_fd
);
84 link_configs_free(ctx
);
88 int link_config_ctx_new(LinkConfigContext
**ret
) {
89 _cleanup_(link_config_ctx_freep
) LinkConfigContext
*ctx
= NULL
;
94 ctx
= new(LinkConfigContext
, 1);
98 *ctx
= (LinkConfigContext
) {
100 .enable_name_policy
= true,
103 *ret
= TAKE_PTR(ctx
);
108 static int link_parse_wol_password(LinkConfig
*config
, const char *str
) {
109 _cleanup_(erase_and_freep
) uint8_t *p
= NULL
;
115 assert_cc(sizeof(struct ether_addr
) == SOPASS_MAX
);
117 p
= new(uint8_t, SOPASS_MAX
);
121 /* Reuse parse_ether_addr(), as their formats are equivalent. */
122 r
= parse_ether_addr(str
, (struct ether_addr
*) p
);
126 erase_and_free(config
->wol_password
);
127 config
->wol_password
= TAKE_PTR(p
);
131 static int link_read_wol_password_from_file(LinkConfig
*config
) {
132 _cleanup_(erase_and_freep
) char *password
= NULL
;
137 if (!config
->wol_password_file
)
140 r
= read_full_file_full(
141 AT_FDCWD
, config
->wol_password_file
, UINT64_MAX
, SIZE_MAX
,
142 READ_FULL_FILE_SECURE
| READ_FULL_FILE_WARN_WORLD_READABLE
| READ_FULL_FILE_CONNECT_SOCKET
,
143 NULL
, &password
, NULL
);
147 return link_parse_wol_password(config
, password
);
150 static int link_read_wol_password_from_cred(LinkConfig
*config
) {
151 _cleanup_free_
char *base
= NULL
, *cred_name
= NULL
;
152 _cleanup_(erase_and_freep
) char *password
= NULL
;
156 assert(config
->filename
);
158 if (config
->wol
== UINT32_MAX
)
159 return 0; /* WakeOnLan= is not specified. */
160 if (!FLAGS_SET(config
->wol
, WAKE_MAGICSECURE
))
161 return 0; /* secureon is not specified in WakeOnLan=. */
162 if (config
->wol_password
)
163 return 0; /* WakeOnLanPassword= is specified. */
164 if (config
->wol_password_file
)
165 return 0; /* a file name is specified in WakeOnLanPassword=, but failed to read it. */
167 r
= path_extract_filename(config
->filename
, &base
);
171 cred_name
= strjoin(base
, ".wol.password");
175 r
= read_credential(cred_name
, (void**) &password
, NULL
);
177 r
= read_credential("wol.password", (void**) &password
, NULL
);
181 return link_parse_wol_password(config
, password
);
184 static int link_adjust_wol_options(LinkConfig
*config
) {
189 r
= link_read_wol_password_from_file(config
);
193 log_warning_errno(r
, "Failed to read WakeOnLan password from %s, ignoring: %m", config
->wol_password_file
);
195 r
= link_read_wol_password_from_cred(config
);
199 log_warning_errno(r
, "Failed to read WakeOnLan password from credential, ignoring: %m");
201 if (config
->wol
!= UINT32_MAX
&& config
->wol_password
)
202 /* Enable WAKE_MAGICSECURE flag when WakeOnLanPassword=. Note that when
203 * WakeOnLanPassword= is set without WakeOnLan=, then ethtool_set_wol() enables
204 * WAKE_MAGICSECURE flag and other flags are not changed. */
205 config
->wol
|= WAKE_MAGICSECURE
;
210 int link_load_one(LinkConfigContext
*ctx
, const char *filename
) {
211 _cleanup_(link_config_freep
) LinkConfig
*config
= NULL
;
212 _cleanup_free_
char *name
= NULL
;
213 const char *dropin_dirname
;
220 r
= null_or_empty_path(filename
);
226 log_debug("Skipping empty file: %s", filename
);
230 name
= strdup(filename
);
234 config
= new(LinkConfig
, 1);
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
,
255 for (i
= 0; i
< ELEMENTSOF(config
->features
); i
++)
256 config
->features
[i
] = -1;
258 dropin_dirname
= strjoina(basename(filename
), ".d");
259 r
= config_parse_many(
260 STRV_MAKE_CONST(filename
),
261 (const char* const*) CONF_PATHS_STRV("systemd/network"),
266 config_item_perf_lookup
, link_config_gperf_lookup
,
267 CONFIG_PARSE_WARN
, config
, NULL
);
271 if (net_match_is_empty(&config
->match
) && !config
->conditions
) {
272 log_warning("%s: No valid settings found in the [Match] section, ignoring file. "
273 "To match all interfaces, add OriginalName=* in the [Match] section.",
278 if (!condition_test_list(config
->conditions
, environ
, NULL
, NULL
, NULL
)) {
279 log_debug("%s: Conditions do not match the system environment, skipping.", filename
);
283 if (IN_SET(config
->mac_address_policy
, MAC_ADDRESS_POLICY_PERSISTENT
, MAC_ADDRESS_POLICY_RANDOM
) &&
284 config
->hw_addr
.length
> 0)
285 log_warning("%s: MACAddress= in [Link] section will be ignored when MACAddressPolicy= "
286 "is set to \"persistent\" or \"random\".",
289 r
= link_adjust_wol_options(config
);
293 r
= sr_iov_drop_invalid_sections(config
->sr_iov_num_vfs
, config
->sr_iov_by_section
);
297 log_debug("Parsed configuration file %s", filename
);
299 LIST_PREPEND(configs
, ctx
->configs
, TAKE_PTR(config
));
303 static bool enable_name_policy(void) {
306 return proc_cmdline_get_bool("net.ifnames", &b
) <= 0 || b
;
309 static int device_unsigned_attribute(sd_device
*device
, const char *attr
, unsigned *type
) {
313 r
= sd_device_get_sysattr_value(device
, attr
, &s
);
315 return log_device_debug_errno(device
, r
, "Failed to query %s: %m", attr
);
317 r
= safe_atou(s
, type
);
319 return log_device_warning_errno(device
, r
, "Failed to parse %s \"%s\": %m", attr
, s
);
321 log_device_debug(device
, "Device has %s=%u", attr
, *type
);
325 int link_config_load(LinkConfigContext
*ctx
) {
326 _cleanup_strv_free_
char **files
= NULL
;
329 link_configs_free(ctx
);
331 if (!enable_name_policy()) {
332 ctx
->enable_name_policy
= false;
333 log_info("Network interface NamePolicy= disabled on kernel command line, ignoring.");
336 /* update timestamp */
337 paths_check_timestamp(NETWORK_DIRS
, &ctx
->network_dirs_ts_usec
, true);
339 r
= conf_files_list_strv(&files
, ".link", NULL
, 0, NETWORK_DIRS
);
341 return log_error_errno(r
, "failed to enumerate link files: %m");
343 STRV_FOREACH_BACKWARDS(f
, files
) {
344 r
= link_load_one(ctx
, *f
);
346 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
352 bool link_config_should_reload(LinkConfigContext
*ctx
) {
353 return paths_check_timestamp(NETWORK_DIRS
, &ctx
->network_dirs_ts_usec
, false);
356 Link
*link_free(Link
*link
) {
360 sd_device_unref(link
->device
);
366 int link_new(LinkConfigContext
*ctx
, sd_netlink
**rtnl
, sd_device
*device
, Link
**ret
) {
367 _cleanup_(link_freep
) Link
*link
= NULL
;
380 .device
= sd_device_ref(device
),
383 r
= sd_device_get_sysname(device
, &link
->ifname
);
387 r
= sd_device_get_ifindex(device
, &link
->ifindex
);
391 r
= sd_device_get_action(device
, &link
->action
);
395 r
= device_unsigned_attribute(device
, "name_assign_type", &link
->name_assign_type
);
397 log_link_debug_errno(link
, r
, "Failed to get \"name_assign_type\" attribute, ignoring: %m");
399 r
= device_unsigned_attribute(device
, "addr_assign_type", &link
->addr_assign_type
);
401 log_link_debug_errno(link
, r
, "Failed to get \"addr_assign_type\" attribute, ignoring: %m");
403 r
= rtnl_get_link_info(rtnl
, link
->ifindex
, &link
->iftype
, &link
->flags
,
404 &link
->kind
, &link
->hw_addr
, &link
->permanent_hw_addr
);
408 if (link
->hw_addr
.length
> 0 && link
->permanent_hw_addr
.length
== 0) {
409 r
= ethtool_get_permanent_hw_addr(&ctx
->ethtool_fd
, link
->ifname
, &link
->permanent_hw_addr
);
411 log_link_debug_errno(link
, r
, "Failed to get permanent hardware address, ignoring: %m");
414 r
= ethtool_get_driver(&ctx
->ethtool_fd
, link
->ifname
, &link
->driver
);
416 log_link_debug_errno(link
, r
, "Failed to get driver, ignoring: %m");
418 *ret
= TAKE_PTR(link
);
422 int link_get_config(LinkConfigContext
*ctx
, Link
*link
) {
428 /* Do not configure loopback interfaces by .link files. */
429 if (link
->flags
& IFF_LOOPBACK
)
432 LIST_FOREACH(configs
, config
, ctx
->configs
) {
433 r
= net_match_config(
437 &link
->permanent_hw_addr
,
442 /* alternative_names = */ NULL
,
443 /* wlan_iftype = */ 0,
451 if (config
->match
.ifname
&& !strv_contains(config
->match
.ifname
, "*") && link
->name_assign_type
== NET_NAME_ENUM
)
452 log_link_warning(link
, "Config file %s is applied to device based on potentially unpredictable interface name.",
455 log_link_debug(link
, "Config file %s is applied", config
->filename
);
457 link
->config
= config
;
464 static int link_apply_ethtool_settings(Link
*link
, int *ethtool_fd
) {
470 assert(link
->config
);
473 config
= link
->config
;
476 r
= ethtool_set_glinksettings(ethtool_fd
, name
,
477 config
->autonegotiation
, config
->advertise
,
478 config
->speed
, config
->duplex
, config
->port
, config
->mdi
);
480 if (config
->autonegotiation
>= 0)
481 log_link_warning_errno(link
, r
, "Could not %s auto negotiation, ignoring: %m",
482 enable_disable(config
->autonegotiation
));
484 if (!eqzero(config
->advertise
))
485 log_link_warning_errno(link
, r
, "Could not set advertise mode, ignoring: %m");
487 if (config
->speed
> 0)
488 log_link_warning_errno(link
, r
, "Could not set speed to %"PRIu64
"Mbps, ignoring: %m",
489 DIV_ROUND_UP(config
->speed
, 1000000));
491 if (config
->duplex
>= 0)
492 log_link_warning_errno(link
, r
, "Could not set duplex to %s, ignoring: %m",
493 duplex_to_string(config
->duplex
));
495 if (config
->port
>= 0)
496 log_link_warning_errno(link
, r
, "Could not set port to '%s', ignoring: %m",
497 port_to_string(config
->port
));
499 if (config
->mdi
!= ETH_TP_MDI_INVALID
)
500 log_link_warning_errno(link
, r
, "Could not set MDI-X to '%s', ignoring: %m",
501 mdi_to_string(config
->mdi
));
504 r
= ethtool_set_wol(ethtool_fd
, name
, config
->wol
, config
->wol_password
);
506 _cleanup_free_
char *str
= NULL
;
508 (void) wol_options_to_string_alloc(config
->wol
, &str
);
509 log_link_warning_errno(link
, r
, "Could not set WakeOnLan%s%s, ignoring: %m",
510 isempty(str
) ? "" : " to ", strempty(str
));
513 r
= ethtool_set_features(ethtool_fd
, name
, config
->features
);
515 log_link_warning_errno(link
, r
, "Could not set offload features, ignoring: %m");
517 r
= ethtool_set_channels(ethtool_fd
, name
, &config
->channels
);
519 log_link_warning_errno(link
, r
, "Could not set channels, ignoring: %m");
521 r
= ethtool_set_nic_buffer_size(ethtool_fd
, name
, &config
->ring
);
523 log_link_warning_errno(link
, r
, "Could not set ring buffer, ignoring: %m");
525 r
= ethtool_set_flow_control(ethtool_fd
, name
, config
->rx_flow_control
, config
->tx_flow_control
, config
->autoneg_flow_control
);
527 log_link_warning_errno(link
, r
, "Could not set flow control, ignoring: %m");
529 r
= ethtool_set_nic_coalesce_settings(ethtool_fd
, name
, &config
->coalesce
);
531 log_link_warning_errno(link
, r
, "Could not set coalesce settings, ignoring: %m");
536 static bool hw_addr_is_valid(Link
*link
, const struct hw_addr_data
*hw_addr
) {
540 switch (link
->iftype
) {
542 /* Refuse all zero and all 0xFF. */
543 assert(hw_addr
->length
== ETH_ALEN
);
544 return !ether_addr_is_null(&hw_addr
->ether
) && !ether_addr_is_broadcast(&hw_addr
->ether
);
546 case ARPHRD_INFINIBAND
:
547 /* The last 8 bytes cannot be zero*/
548 assert(hw_addr
->length
== INFINIBAND_ALEN
);
549 return !memeqzero(hw_addr
->bytes
+ INFINIBAND_ALEN
- 8, 8);
552 assert_not_reached();
556 static int link_generate_new_hw_addr(Link
*link
, struct hw_addr_data
*ret
) {
557 struct hw_addr_data hw_addr
= HW_ADDR_NULL
;
558 bool is_static
= false;
564 assert(link
->config
);
565 assert(link
->device
);
568 if (link
->hw_addr
.length
== 0)
571 if (link
->config
->mac_address_policy
== MAC_ADDRESS_POLICY_NONE
) {
572 log_link_debug(link
, "Using static MAC address.");
573 hw_addr
= link
->config
->hw_addr
;
578 if (!IN_SET(link
->iftype
, ARPHRD_ETHER
, ARPHRD_INFINIBAND
))
581 switch (link
->addr_assign_type
) {
583 log_link_debug(link
, "MAC address on the device already set by userspace.");
585 case NET_ADDR_STOLEN
:
586 log_link_debug(link
, "MAC address on the device already set based on another device.");
588 case NET_ADDR_RANDOM
:
592 log_link_warning(link
, "Unknown addr_assign_type %u, ignoring", link
->addr_assign_type
);
596 if ((link
->config
->mac_address_policy
== MAC_ADDRESS_POLICY_RANDOM
) == (link
->addr_assign_type
== NET_ADDR_RANDOM
)) {
597 log_link_debug(link
, "MAC address on the device already matches policy \"%s\".",
598 mac_address_policy_to_string(link
->config
->mac_address_policy
));
602 hw_addr
= (struct hw_addr_data
) {
603 .length
= arphrd_to_hw_addr_len(link
->iftype
),
606 switch (link
->iftype
) {
609 len
= hw_addr
.length
;
611 case ARPHRD_INFINIBAND
:
612 p
= hw_addr
.bytes
+ INFINIBAND_ALEN
- 8;
616 assert_not_reached();
619 if (link
->config
->mac_address_policy
== MAC_ADDRESS_POLICY_RANDOM
)
620 /* We require genuine randomness here, since we want to make sure we won't collide with other
621 * systems booting up at the very same time. */
623 r
= genuine_random_bytes(p
, len
, 0);
625 return log_link_warning_errno(link
, r
, "Failed to acquire random data to generate MAC address: %m");
627 if (hw_addr_is_valid(link
, &hw_addr
))
634 r
= net_get_unique_predictable_data(link
->device
,
635 naming_scheme_has(NAMING_STABLE_VIRTUAL_MACS
),
638 return log_link_warning_errno(link
, r
, "Could not generate persistent MAC address: %m");
640 assert(len
<= sizeof(result
));
641 memcpy(p
, &result
, len
);
642 if (!hw_addr_is_valid(link
, &hw_addr
))
643 return log_link_warning_errno(link
, SYNTHETIC_ERRNO(EINVAL
),
644 "Could not generate valid persistent MAC address: %m");
649 r
= net_verify_hardware_address(link
->ifname
, is_static
, link
->iftype
, &link
->hw_addr
, &hw_addr
);
653 if (hw_addr_equal(&link
->hw_addr
, &hw_addr
)) {
658 if (hw_addr
.length
> 0)
659 log_link_debug(link
, "Applying %s MAC address: %s",
660 link
->config
->mac_address_policy
== MAC_ADDRESS_POLICY_NONE
? "static" :
661 mac_address_policy_to_string(link
->config
->mac_address_policy
),
662 HW_ADDR_TO_STR(&hw_addr
));
668 static int link_apply_rtnl_settings(Link
*link
, sd_netlink
**rtnl
) {
669 struct hw_addr_data hw_addr
= {};
674 assert(link
->config
);
677 config
= link
->config
;
679 (void) link_generate_new_hw_addr(link
, &hw_addr
);
681 r
= rtnl_set_link_properties(rtnl
, link
->ifindex
, config
->alias
, &hw_addr
,
682 config
->txqueues
, config
->rxqueues
, config
->txqueuelen
,
683 config
->mtu
, config
->gso_max_size
, config
->gso_max_segments
);
685 log_link_warning_errno(link
, r
,
686 "Could not set Alias=, MACAddress=/MACAddressPolicy=, "
687 "TransmitQueues=, ReceiveQueues=, TransmitQueueLength=, MTUBytes=, "
688 "GenericSegmentOffloadMaxBytes= or GenericSegmentOffloadMaxSegments=, "
694 static int link_generate_new_name(Link
*link
, bool enable_name_policy
) {
699 assert(link
->config
);
700 assert(link
->device
);
702 config
= link
->config
;
703 device
= link
->device
;
705 if (link
->action
== SD_DEVICE_MOVE
) {
706 log_link_debug(link
, "Skipping to apply Name= and NamePolicy= on '%s' uevent.",
707 device_action_to_string(link
->action
));
711 if (IN_SET(link
->name_assign_type
, NET_NAME_USER
, NET_NAME_RENAMED
) &&
712 !naming_scheme_has(NAMING_ALLOW_RERENAMES
)) {
713 log_link_debug(link
, "Device already has a name given by userspace, not renaming.");
717 if (enable_name_policy
&& config
->name_policy
)
718 for (NamePolicy
*policy
= config
->name_policy
; *policy
!= _NAMEPOLICY_INVALID
; policy
++) {
719 const char *new_name
= NULL
;
722 case NAMEPOLICY_KERNEL
:
723 if (link
->name_assign_type
!= NET_NAME_PREDICTABLE
)
726 /* The kernel claims to have given a predictable name, keep it. */
727 log_link_debug(link
, "Policy *%s*: keeping predictable kernel name",
728 name_policy_to_string(*policy
));
730 case NAMEPOLICY_KEEP
:
731 if (!IN_SET(link
->name_assign_type
, NET_NAME_USER
, NET_NAME_RENAMED
))
734 log_link_debug(link
, "Policy *%s*: keeping existing userspace name",
735 name_policy_to_string(*policy
));
737 case NAMEPOLICY_DATABASE
:
738 (void) sd_device_get_property_value(device
, "ID_NET_NAME_FROM_DATABASE", &new_name
);
740 case NAMEPOLICY_ONBOARD
:
741 (void) sd_device_get_property_value(device
, "ID_NET_NAME_ONBOARD", &new_name
);
743 case NAMEPOLICY_SLOT
:
744 (void) sd_device_get_property_value(device
, "ID_NET_NAME_SLOT", &new_name
);
746 case NAMEPOLICY_PATH
:
747 (void) sd_device_get_property_value(device
, "ID_NET_NAME_PATH", &new_name
);
750 (void) sd_device_get_property_value(device
, "ID_NET_NAME_MAC", &new_name
);
753 assert_not_reached();
755 if (ifname_valid(new_name
)) {
756 log_link_debug(link
, "Policy *%s* yields \"%s\".", name_policy_to_string(*policy
), new_name
);
757 link
->new_name
= new_name
;
762 if (link
->config
->name
) {
763 log_link_debug(link
, "Policies didn't yield a name, using specified Name=%s.", link
->config
->name
);
764 link
->new_name
= link
->config
->name
;
768 log_link_debug(link
, "Policies didn't yield a name and Name= is not given, not renaming.");
770 link
->new_name
= link
->ifname
;
774 static int link_apply_alternative_names(Link
*link
, sd_netlink
**rtnl
) {
775 _cleanup_strv_free_
char **altnames
= NULL
, **current_altnames
= NULL
;
781 assert(link
->config
);
782 assert(link
->device
);
785 config
= link
->config
;
786 device
= link
->device
;
788 if (config
->alternative_names
) {
789 altnames
= strv_copy(config
->alternative_names
);
794 if (config
->alternative_names_policy
)
795 for (NamePolicy
*p
= config
->alternative_names_policy
; *p
!= _NAMEPOLICY_INVALID
; p
++) {
796 const char *n
= NULL
;
799 case NAMEPOLICY_DATABASE
:
800 (void) sd_device_get_property_value(device
, "ID_NET_NAME_FROM_DATABASE", &n
);
802 case NAMEPOLICY_ONBOARD
:
803 (void) sd_device_get_property_value(device
, "ID_NET_NAME_ONBOARD", &n
);
805 case NAMEPOLICY_SLOT
:
806 (void) sd_device_get_property_value(device
, "ID_NET_NAME_SLOT", &n
);
808 case NAMEPOLICY_PATH
:
809 (void) sd_device_get_property_value(device
, "ID_NET_NAME_PATH", &n
);
812 (void) sd_device_get_property_value(device
, "ID_NET_NAME_MAC", &n
);
815 assert_not_reached();
818 r
= strv_extend(&altnames
, n
);
825 strv_remove(altnames
, link
->new_name
);
826 strv_remove(altnames
, link
->ifname
);
828 r
= rtnl_get_link_alternative_names(rtnl
, link
->ifindex
, ¤t_altnames
);
830 log_link_debug_errno(link
, r
, "Failed to get alternative names, ignoring: %m");
832 STRV_FOREACH(p
, current_altnames
)
833 strv_remove(altnames
, *p
);
837 r
= rtnl_set_link_alternative_names(rtnl
, link
->ifindex
, altnames
);
839 log_link_full_errno(link
, r
== -EOPNOTSUPP
? LOG_DEBUG
: LOG_WARNING
, r
,
840 "Could not set AlternativeName= or apply AlternativeNamesPolicy=, ignoring: %m");
845 static int sr_iov_configure(Link
*link
, sd_netlink
**rtnl
, SRIOV
*sr_iov
) {
846 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
;
851 assert(link
->ifindex
> 0);
854 r
= sd_netlink_open(rtnl
);
859 r
= sd_rtnl_message_new_link(*rtnl
, &req
, RTM_SETLINK
, link
->ifindex
);
863 r
= sr_iov_set_netlink_message(sr_iov
, req
);
867 r
= sd_netlink_call(*rtnl
, req
, 0, NULL
);
874 static int link_apply_sr_iov_config(Link
*link
, sd_netlink
**rtnl
) {
880 assert(link
->config
);
881 assert(link
->device
);
883 r
= sr_iov_set_num_vfs(link
->device
, link
->config
->sr_iov_num_vfs
, link
->config
->sr_iov_by_section
);
885 log_link_warning_errno(link
, r
, "Failed to set the number of SR-IOV virtual functions, ignoring: %m");
887 if (ordered_hashmap_isempty(link
->config
->sr_iov_by_section
))
890 r
= sr_iov_get_num_vfs(link
->device
, &n
);
892 log_link_warning_errno(link
, r
, "Failed to get the number of SR-IOV virtual functions, ignoring [SR-IOV] sections: %m");
896 log_link_warning(link
, "No SR-IOV virtual function exists, ignoring [SR-IOV] sections: %m");
900 ORDERED_HASHMAP_FOREACH(sr_iov
, link
->config
->sr_iov_by_section
) {
901 if (sr_iov
->vf
>= n
) {
902 log_link_warning(link
, "SR-IOV virtual function %"PRIu32
" does not exist, ignoring.", sr_iov
->vf
);
906 r
= sr_iov_configure(link
, rtnl
, sr_iov
);
908 log_link_warning_errno(link
, r
,
909 "Failed to configure SR-IOV virtual function %"PRIu32
", ignoring: %m",
916 int link_apply_config(LinkConfigContext
*ctx
, sd_netlink
**rtnl
, Link
*link
) {
923 if (!IN_SET(link
->action
, SD_DEVICE_ADD
, SD_DEVICE_BIND
, SD_DEVICE_MOVE
)) {
924 log_link_debug(link
, "Skipping to apply .link settings on '%s' uevent.",
925 device_action_to_string(link
->action
));
927 link
->new_name
= link
->ifname
;
931 r
= link_apply_ethtool_settings(link
, &ctx
->ethtool_fd
);
935 r
= link_apply_rtnl_settings(link
, rtnl
);
939 r
= link_generate_new_name(link
, ctx
->enable_name_policy
);
943 r
= link_apply_alternative_names(link
, rtnl
);
947 r
= link_apply_sr_iov_config(link
, rtnl
);
954 int config_parse_ifalias(
956 const char *filename
,
959 unsigned section_line
,
973 if (!isempty(rvalue
)) {
978 if (!ascii_is_valid(rvalue
)) {
979 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
980 "Interface alias is not ASCII clean, ignoring assignment: %s", rvalue
);
984 if (strlen(rvalue
) >= IFALIASZ
) {
985 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0,
986 "Interface alias is too long, ignoring assignment: %s", rvalue
);
990 return free_and_strdup_warn(s
, rvalue
);
993 int config_parse_rx_tx_queues(
995 const char *filename
,
998 unsigned section_line
,
1005 uint32_t k
, *v
= data
;
1008 if (isempty(rvalue
)) {
1013 r
= safe_atou32(rvalue
, &k
);
1015 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
, "Failed to parse %s=, ignoring assignment: %s.", lvalue
, rvalue
);
1018 if (k
== 0 || k
> 4096) {
1019 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0, "Invalid %s=, ignoring assignment: %s.", lvalue
, rvalue
);
1027 int config_parse_txqueuelen(
1029 const char *filename
,
1031 const char *section
,
1032 unsigned section_line
,
1039 uint32_t k
, *v
= data
;
1042 if (isempty(rvalue
)) {
1047 r
= safe_atou32(rvalue
, &k
);
1049 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
, "Failed to parse %s=, ignoring assignment: %s.", lvalue
, rvalue
);
1052 if (k
== UINT32_MAX
) {
1053 log_syntax(unit
, LOG_WARNING
, filename
, line
, 0, "Invalid %s=, ignoring assignment: %s.", lvalue
, rvalue
);
1061 int config_parse_wol_password(
1063 const char *filename
,
1065 const char *section
,
1066 unsigned section_line
,
1073 LinkConfig
*config
= userdata
;
1081 if (isempty(rvalue
)) {
1082 config
->wol_password
= erase_and_free(config
->wol_password
);
1083 config
->wol_password_file
= mfree(config
->wol_password_file
);
1087 if (path_is_absolute(rvalue
) && path_is_safe(rvalue
)) {
1088 config
->wol_password
= erase_and_free(config
->wol_password
);
1089 return free_and_strdup_warn(&config
->wol_password_file
, rvalue
);
1092 warn_file_is_world_accessible(filename
, NULL
, unit
, line
);
1094 r
= link_parse_wol_password(config
, rvalue
);
1098 log_syntax(unit
, LOG_WARNING
, filename
, line
, r
,
1099 "Failed to parse %s=, ignoring assignment: %s.", lvalue
, rvalue
);
1103 config
->wol_password_file
= mfree(config
->wol_password_file
);
1107 static const char* const mac_address_policy_table
[_MAC_ADDRESS_POLICY_MAX
] = {
1108 [MAC_ADDRESS_POLICY_PERSISTENT
] = "persistent",
1109 [MAC_ADDRESS_POLICY_RANDOM
] = "random",
1110 [MAC_ADDRESS_POLICY_NONE
] = "none",
1113 DEFINE_STRING_TABLE_LOOKUP(mac_address_policy
, MACAddressPolicy
);
1114 DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(
1115 config_parse_mac_address_policy
,
1118 MAC_ADDRESS_POLICY_NONE
,
1119 "Failed to parse MAC address policy");
1121 DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy
, name_policy
, NamePolicy
,
1122 _NAMEPOLICY_INVALID
,
1123 "Failed to parse interface name policy");
1125 DEFINE_CONFIG_PARSE_ENUMV(config_parse_alternative_names_policy
, alternative_names_policy
, NamePolicy
,
1126 _NAMEPOLICY_INVALID
,
1127 "Failed to parse alternative names policy");