1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include <linux/netdevice.h>
4 #include <netinet/ether.h>
8 #include "sd-netlink.h"
10 #include "alloc-util.h"
11 #include "conf-files.h"
12 #include "conf-parser.h"
14 #include "device-util.h"
15 #include "ethtool-util.h"
17 #include "link-config.h"
19 #include "memory-util.h"
20 #include "netif-naming-scheme.h"
21 #include "netlink-util.h"
22 #include "network-internal.h"
23 #include "parse-util.h"
24 #include "path-lookup.h"
25 #include "path-util.h"
26 #include "proc-cmdline.h"
27 #include "random-util.h"
28 #include "stat-util.h"
29 #include "string-table.h"
30 #include "string-util.h"
33 struct link_config_ctx
{
34 LIST_HEAD(link_config
, links
);
38 bool enable_name_policy
;
42 usec_t network_dirs_ts_usec
;
45 static void link_config_free(link_config
*link
) {
51 set_free_free(link
->match_mac
);
52 set_free_free(link
->match_permanent_mac
);
53 strv_free(link
->match_path
);
54 strv_free(link
->match_driver
);
55 strv_free(link
->match_type
);
56 strv_free(link
->match_name
);
57 strv_free(link
->match_property
);
58 condition_free_list(link
->conditions
);
60 free(link
->description
);
62 free(link
->name_policy
);
64 strv_free(link
->alternative_names
);
65 free(link
->alternative_names_policy
);
71 DEFINE_TRIVIAL_CLEANUP_FUNC(link_config
*, link_config_free
);
73 static void link_configs_free(link_config_ctx
*ctx
) {
74 link_config
*link
, *link_next
;
79 LIST_FOREACH_SAFE(links
, link
, link_next
, ctx
->links
)
80 link_config_free(link
);
83 void link_config_ctx_free(link_config_ctx
*ctx
) {
87 safe_close(ctx
->ethtool_fd
);
89 sd_netlink_unref(ctx
->rtnl
);
91 link_configs_free(ctx
);
98 int link_config_ctx_new(link_config_ctx
**ret
) {
99 _cleanup_(link_config_ctx_freep
) link_config_ctx
*ctx
= NULL
;
104 ctx
= new0(link_config_ctx
, 1);
108 LIST_HEAD_INIT(ctx
->links
);
110 ctx
->ethtool_fd
= -1;
112 ctx
->enable_name_policy
= true;
114 *ret
= TAKE_PTR(ctx
);
119 int link_load_one(link_config_ctx
*ctx
, const char *filename
) {
120 _cleanup_(link_config_freep
) link_config
*link
= NULL
;
121 _cleanup_fclose_
FILE *file
= NULL
;
122 _cleanup_free_
char *name
= NULL
;
129 file
= fopen(filename
, "re");
131 return errno
== ENOENT
? 0 : -errno
;
133 if (null_or_empty_fd(fileno(file
))) {
134 log_debug("Skipping empty file: %s", filename
);
138 name
= strdup(filename
);
142 link
= new(link_config
, 1);
146 *link
= (link_config
) {
147 .filename
= TAKE_PTR(name
),
148 .mac_address_policy
= _MAC_ADDRESS_POLICY_INVALID
,
150 .duplex
= _DUP_INVALID
,
151 .port
= _NET_DEV_PORT_INVALID
,
152 .autonegotiation
= -1,
153 .rx_flow_control
= -1,
154 .tx_flow_control
= -1,
155 .autoneg_flow_control
= -1,
158 for (i
= 0; i
< ELEMENTSOF(link
->features
); i
++)
159 link
->features
[i
] = -1;
161 r
= config_parse(NULL
, filename
, file
,
163 config_item_perf_lookup
, link_config_gperf_lookup
,
164 CONFIG_PARSE_WARN
, link
,
169 if (set_isempty(link
->match_mac
) && set_isempty(link
->match_permanent_mac
) &&
170 strv_isempty(link
->match_path
) && strv_isempty(link
->match_driver
) && strv_isempty(link
->match_type
) &&
171 strv_isempty(link
->match_name
) && strv_isempty(link
->match_property
) && !link
->conditions
) {
172 log_warning("%s: No valid settings found in the [Match] section, ignoring file. "
173 "To match all interfaces, add OriginalName=* in the [Match] section.",
178 if (!condition_test_list(link
->conditions
, environ
, NULL
, NULL
, NULL
)) {
179 log_debug("%s: Conditions do not match the system environment, skipping.", filename
);
183 log_debug("Parsed configuration file %s", filename
);
185 LIST_PREPEND(links
, ctx
->links
, TAKE_PTR(link
));
189 static bool enable_name_policy(void) {
192 return proc_cmdline_get_bool("net.ifnames", &b
) <= 0 || b
;
195 static int link_unsigned_attribute(sd_device
*device
, const char *attr
, unsigned *type
) {
199 r
= sd_device_get_sysattr_value(device
, attr
, &s
);
201 return log_device_debug_errno(device
, r
, "Failed to query %s: %m", attr
);
203 r
= safe_atou(s
, type
);
205 return log_device_warning_errno(device
, r
, "Failed to parse %s \"%s\": %m", attr
, s
);
207 log_device_debug(device
, "Device has %s=%u", attr
, *type
);
211 int link_config_load(link_config_ctx
*ctx
) {
212 _cleanup_strv_free_
char **files
= NULL
;
216 link_configs_free(ctx
);
218 if (!enable_name_policy()) {
219 ctx
->enable_name_policy
= false;
220 log_info("Network interface NamePolicy= disabled on kernel command line, ignoring.");
223 /* update timestamp */
224 paths_check_timestamp(NETWORK_DIRS
, &ctx
->network_dirs_ts_usec
, true);
226 r
= conf_files_list_strv(&files
, ".link", NULL
, 0, NETWORK_DIRS
);
228 return log_error_errno(r
, "failed to enumerate link files: %m");
230 STRV_FOREACH_BACKWARDS(f
, files
) {
231 r
= link_load_one(ctx
, *f
);
233 log_error_errno(r
, "Failed to load %s, ignoring: %m", *f
);
239 bool link_config_should_reload(link_config_ctx
*ctx
) {
240 return paths_check_timestamp(NETWORK_DIRS
, &ctx
->network_dirs_ts_usec
, false);
243 int link_config_get(link_config_ctx
*ctx
, sd_device
*device
, link_config
**ret
) {
244 struct ether_addr permanent_mac
= {};
245 unsigned short iftype
= 0;
254 r
= sd_device_get_sysname(device
, &name
);
258 r
= sd_device_get_ifindex(device
, &ifindex
);
262 r
= rtnl_get_link_iftype(&ctx
->rtnl
, ifindex
, &iftype
);
266 r
= ethtool_get_permanent_macaddr(&ctx
->ethtool_fd
, name
, &permanent_mac
);
268 log_device_debug_errno(device
, r
, "Failed to get permanent MAC address, ignoring: %m");
270 LIST_FOREACH(links
, link
, ctx
->links
) {
271 if (net_match_config(link
->match_mac
, link
->match_permanent_mac
, link
->match_path
, link
->match_driver
,
272 link
->match_type
, link
->match_name
, link
->match_property
, NULL
, NULL
, NULL
,
273 device
, NULL
, &permanent_mac
, NULL
, iftype
, NULL
, NULL
, 0, NULL
, NULL
)) {
274 if (link
->match_name
&& !strv_contains(link
->match_name
, "*")) {
275 unsigned name_assign_type
= NET_NAME_UNKNOWN
;
277 (void) link_unsigned_attribute(device
, "name_assign_type", &name_assign_type
);
279 if (name_assign_type
== NET_NAME_ENUM
) {
280 log_device_warning(device
, "Config file %s applies to device based on potentially unpredictable interface name",
285 } else if (name_assign_type
== NET_NAME_RENAMED
) {
286 log_device_warning(device
, "Config file %s matches device based on renamed interface name, ignoring",
293 log_device_debug(device
, "Config file %s is applied", link
->filename
);
304 static int get_mac(sd_device
*device
, MACAddressPolicy policy
, struct ether_addr
*mac
) {
306 bool want_random
= policy
== MAC_ADDRESS_POLICY_RANDOM
;
309 assert(IN_SET(policy
, MAC_ADDRESS_POLICY_RANDOM
, MAC_ADDRESS_POLICY_PERSISTENT
));
311 r
= link_unsigned_attribute(device
, "addr_assign_type", &addr_type
);
316 return log_device_debug(device
, "MAC on the device already set by userspace");
317 case NET_ADDR_STOLEN
:
318 return log_device_debug(device
, "MAC on the device already set based on another device");
319 case NET_ADDR_RANDOM
:
323 log_device_warning(device
, "Unknown addr_assign_type %u, ignoring", addr_type
);
327 if (want_random
== (addr_type
== NET_ADDR_RANDOM
))
328 return log_device_debug(device
, "MAC on the device already matches policy *%s*",
329 mac_address_policy_to_string(policy
));
332 log_device_debug(device
, "Using random bytes to generate MAC");
334 /* We require genuine randomness here, since we want to make sure we won't collide with other
335 * systems booting up at the very same time. We do allow RDRAND however, since this is not
336 * cryptographic key material. */
337 r
= genuine_random_bytes(mac
->ether_addr_octet
, ETH_ALEN
, RANDOM_ALLOW_RDRAND
);
339 return log_device_error_errno(device
, r
, "Failed to acquire random data to generate MAC: %m");
343 r
= net_get_unique_predictable_data(device
,
344 naming_scheme_has(NAMING_STABLE_VIRTUAL_MACS
),
347 return log_device_warning_errno(device
, r
, "Could not generate persistent MAC: %m");
349 log_device_debug(device
, "Using generated persistent MAC address");
350 assert_cc(ETH_ALEN
<= sizeof(result
));
351 memcpy(mac
->ether_addr_octet
, &result
, ETH_ALEN
);
354 /* see eth_random_addr in the kernel */
355 mac
->ether_addr_octet
[0] &= 0xfe; /* clear multicast bit */
356 mac
->ether_addr_octet
[0] |= 0x02; /* set local assignment bit (IEEE802) */
360 int link_config_apply(link_config_ctx
*ctx
, link_config
*config
,
361 sd_device
*device
, const char **name
) {
362 _cleanup_strv_free_
char **altnames
= NULL
, **current_altnames
= NULL
;
363 struct ether_addr generated_mac
;
364 struct ether_addr
*mac
= NULL
;
365 const char *new_name
= NULL
;
366 const char *old_name
;
367 unsigned speed
, name_type
= NET_NAME_UNKNOWN
;
376 r
= sd_device_get_sysname(device
, &old_name
);
380 r
= ethtool_set_glinksettings(&ctx
->ethtool_fd
, old_name
,
381 config
->autonegotiation
, config
->advertise
,
382 config
->speed
, config
->duplex
, config
->port
);
385 if (config
->port
!= _NET_DEV_PORT_INVALID
)
386 log_warning_errno(r
, "Could not set port (%s) of %s: %m", port_to_string(config
->port
), old_name
);
388 if (!eqzero(config
->advertise
))
389 log_warning_errno(r
, "Could not set advertise mode: %m"); /* TODO: include modes in the log message. */
392 speed
= DIV_ROUND_UP(config
->speed
, 1000000);
393 if (r
== -EOPNOTSUPP
) {
394 r
= ethtool_set_speed(&ctx
->ethtool_fd
, old_name
, speed
, config
->duplex
);
396 log_warning_errno(r
, "Could not set speed of %s to %u Mbps: %m", old_name
, speed
);
400 if (config
->duplex
!= _DUP_INVALID
)
401 log_warning_errno(r
, "Could not set duplex of %s to %s: %m", old_name
, duplex_to_string(config
->duplex
));
404 r
= ethtool_set_wol(&ctx
->ethtool_fd
, old_name
, config
->wol
);
406 log_warning_errno(r
, "Could not set WakeOnLan of %s to %s: %m",
407 old_name
, wol_to_string(config
->wol
));
409 r
= ethtool_set_features(&ctx
->ethtool_fd
, old_name
, config
->features
);
411 log_warning_errno(r
, "Could not set offload features of %s: %m", old_name
);
413 if (config
->channels
.rx_count_set
|| config
->channels
.tx_count_set
|| config
->channels
.other_count_set
|| config
->channels
.combined_count_set
) {
414 r
= ethtool_set_channels(&ctx
->ethtool_fd
, old_name
, &config
->channels
);
416 log_warning_errno(r
, "Could not set channels of %s: %m", old_name
);
419 if (config
->ring
.rx_pending_set
|| config
->ring
.rx_mini_pending_set
|| config
->ring
.rx_jumbo_pending_set
|| config
->ring
.tx_pending_set
) {
420 r
= ethtool_set_nic_buffer_size(&ctx
->ethtool_fd
, old_name
, &config
->ring
);
422 log_warning_errno(r
, "Could not set ring buffer of %s: %m", old_name
);
425 if (config
->rx_flow_control
>= 0 || config
->tx_flow_control
>= 0 || config
->autoneg_flow_control
>= 0) {
426 r
= ethtool_set_flow_control(&ctx
->ethtool_fd
, old_name
, config
->rx_flow_control
, config
->tx_flow_control
, config
->autoneg_flow_control
);
428 log_warning_errno(r
, "Could not set flow control of %s: %m", old_name
);
431 r
= sd_device_get_ifindex(device
, &ifindex
);
433 return log_device_warning_errno(device
, r
, "Could not find ifindex: %m");
435 (void) link_unsigned_attribute(device
, "name_assign_type", &name_type
);
437 if (IN_SET(name_type
, NET_NAME_USER
, NET_NAME_RENAMED
)
438 && !naming_scheme_has(NAMING_ALLOW_RERENAMES
)) {
439 log_device_debug(device
, "Device already has a name given by userspace, not renaming.");
443 if (ctx
->enable_name_policy
&& config
->name_policy
)
444 for (NamePolicy
*p
= config
->name_policy
; *p
!= _NAMEPOLICY_INVALID
; p
++) {
448 case NAMEPOLICY_KERNEL
:
449 if (name_type
!= NET_NAME_PREDICTABLE
)
452 /* The kernel claims to have given a predictable name, keep it. */
453 log_device_debug(device
, "Policy *%s*: keeping predictable kernel name",
454 name_policy_to_string(policy
));
456 case NAMEPOLICY_KEEP
:
457 if (!IN_SET(name_type
, NET_NAME_USER
, NET_NAME_RENAMED
))
460 log_device_debug(device
, "Policy *%s*: keeping existing userspace name",
461 name_policy_to_string(policy
));
463 case NAMEPOLICY_DATABASE
:
464 (void) sd_device_get_property_value(device
, "ID_NET_NAME_FROM_DATABASE", &new_name
);
466 case NAMEPOLICY_ONBOARD
:
467 (void) sd_device_get_property_value(device
, "ID_NET_NAME_ONBOARD", &new_name
);
469 case NAMEPOLICY_SLOT
:
470 (void) sd_device_get_property_value(device
, "ID_NET_NAME_SLOT", &new_name
);
472 case NAMEPOLICY_PATH
:
473 (void) sd_device_get_property_value(device
, "ID_NET_NAME_PATH", &new_name
);
476 (void) sd_device_get_property_value(device
, "ID_NET_NAME_MAC", &new_name
);
479 assert_not_reached("invalid policy");
481 if (ifname_valid(new_name
))
486 log_device_debug(device
, "Policy *%s* yields \"%s\".", name_policy_to_string(policy
), new_name
);
487 else if (config
->name
) {
488 new_name
= config
->name
;
489 log_device_debug(device
, "Policies didn't yield a name, using specified Name=%s.", new_name
);
491 log_device_debug(device
, "Policies didn't yield a name and Name= is not given, not renaming.");
494 if (IN_SET(config
->mac_address_policy
, MAC_ADDRESS_POLICY_PERSISTENT
, MAC_ADDRESS_POLICY_RANDOM
)) {
495 if (get_mac(device
, config
->mac_address_policy
, &generated_mac
) > 0)
496 mac
= &generated_mac
;
500 r
= rtnl_set_link_properties(&ctx
->rtnl
, ifindex
, config
->alias
, mac
, config
->mtu
);
502 return log_warning_errno(r
, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name
);
504 if (config
->alternative_names
) {
505 altnames
= strv_copy(config
->alternative_names
);
510 if (config
->alternative_names_policy
)
511 for (NamePolicy
*p
= config
->alternative_names_policy
; *p
!= _NAMEPOLICY_INVALID
; p
++) {
512 const char *n
= NULL
;
515 case NAMEPOLICY_DATABASE
:
516 (void) sd_device_get_property_value(device
, "ID_NET_NAME_FROM_DATABASE", &n
);
518 case NAMEPOLICY_ONBOARD
:
519 (void) sd_device_get_property_value(device
, "ID_NET_NAME_ONBOARD", &n
);
521 case NAMEPOLICY_SLOT
:
522 (void) sd_device_get_property_value(device
, "ID_NET_NAME_SLOT", &n
);
524 case NAMEPOLICY_PATH
:
525 (void) sd_device_get_property_value(device
, "ID_NET_NAME_PATH", &n
);
528 (void) sd_device_get_property_value(device
, "ID_NET_NAME_MAC", &n
);
531 assert_not_reached("invalid policy");
534 r
= strv_extend(&altnames
, n
);
541 strv_remove(altnames
, new_name
);
542 strv_remove(altnames
, old_name
);
544 r
= rtnl_get_link_alternative_names(&ctx
->rtnl
, ifindex
, ¤t_altnames
);
546 log_debug_errno(r
, "Failed to get alternative names on %s, ignoring: %m", old_name
);
549 STRV_FOREACH(p
, current_altnames
)
550 strv_remove(altnames
, *p
);
554 r
= rtnl_set_link_alternative_names(&ctx
->rtnl
, ifindex
, altnames
);
555 if (r
== -EOPNOTSUPP
)
556 log_debug_errno(r
, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s, ignoring: %m", old_name
);
558 return log_warning_errno(r
, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s: %m", old_name
);
565 int link_get_driver(link_config_ctx
*ctx
, sd_device
*device
, char **ret
) {
570 r
= sd_device_get_sysname(device
, &name
);
574 r
= ethtool_get_driver(&ctx
->ethtool_fd
, name
, &driver
);
582 static const char* const mac_address_policy_table
[_MAC_ADDRESS_POLICY_MAX
] = {
583 [MAC_ADDRESS_POLICY_PERSISTENT
] = "persistent",
584 [MAC_ADDRESS_POLICY_RANDOM
] = "random",
585 [MAC_ADDRESS_POLICY_NONE
] = "none",
588 DEFINE_STRING_TABLE_LOOKUP(mac_address_policy
, MACAddressPolicy
);
589 DEFINE_CONFIG_PARSE_ENUM(config_parse_mac_address_policy
, mac_address_policy
, MACAddressPolicy
,
590 "Failed to parse MAC address policy");
592 static const char* const name_policy_table
[_NAMEPOLICY_MAX
] = {
593 [NAMEPOLICY_KERNEL
] = "kernel",
594 [NAMEPOLICY_KEEP
] = "keep",
595 [NAMEPOLICY_DATABASE
] = "database",
596 [NAMEPOLICY_ONBOARD
] = "onboard",
597 [NAMEPOLICY_SLOT
] = "slot",
598 [NAMEPOLICY_PATH
] = "path",
599 [NAMEPOLICY_MAC
] = "mac",
602 DEFINE_STRING_TABLE_LOOKUP(name_policy
, NamePolicy
);
603 DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy
, name_policy
, NamePolicy
,
605 "Failed to parse interface name policy");
607 static const char* const alternative_names_policy_table
[_NAMEPOLICY_MAX
] = {
608 [NAMEPOLICY_DATABASE
] = "database",
609 [NAMEPOLICY_ONBOARD
] = "onboard",
610 [NAMEPOLICY_SLOT
] = "slot",
611 [NAMEPOLICY_PATH
] = "path",
612 [NAMEPOLICY_MAC
] = "mac",
615 DEFINE_STRING_TABLE_LOOKUP(alternative_names_policy
, NamePolicy
);
616 DEFINE_CONFIG_PARSE_ENUMV(config_parse_alternative_names_policy
, alternative_names_policy
, NamePolicy
,
618 "Failed to parse alternative names policy");