]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/udev/net/link-config.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <netinet/ether.h>
23 #include <linux/netdevice.h>
25 #include "sd-netlink.h"
27 #include "conf-files.h"
28 #include "conf-parser.h"
29 #include "ethtool-util.h"
31 #include "libudev-private.h"
32 #include "link-config.h"
35 #include "netlink-util.h"
36 #include "network-internal.h"
37 #include "parse-util.h"
38 #include "path-util.h"
39 #include "random-util.h"
40 #include "string-util.h"
44 struct link_config_ctx
{
45 LIST_HEAD(link_config
, links
);
49 bool enable_name_policy
;
53 usec_t link_dirs_ts_usec
;
56 static const char* const link_dirs
[] = {
57 "/etc/systemd/network",
58 "/run/systemd/network",
59 "/usr/lib/systemd/network",
61 "/lib/systemd/network",
65 static void link_config_free(link_config
*link
) {
71 free(link
->match_mac
);
72 strv_free(link
->match_path
);
73 strv_free(link
->match_driver
);
74 strv_free(link
->match_type
);
75 free(link
->match_name
);
76 free(link
->match_host
);
77 free(link
->match_virt
);
78 free(link
->match_kernel
);
79 free(link
->match_arch
);
81 free(link
->description
);
83 free(link
->name_policy
);
90 DEFINE_TRIVIAL_CLEANUP_FUNC(link_config
*, link_config_free
);
92 static void link_configs_free(link_config_ctx
*ctx
) {
93 link_config
*link
, *link_next
;
98 LIST_FOREACH_SAFE(links
, link
, link_next
, ctx
->links
)
99 link_config_free(link
);
102 void link_config_ctx_free(link_config_ctx
*ctx
) {
106 safe_close(ctx
->ethtool_fd
);
108 sd_netlink_unref(ctx
->rtnl
);
110 link_configs_free(ctx
);
117 DEFINE_TRIVIAL_CLEANUP_FUNC(link_config_ctx
*, link_config_ctx_free
);
119 int link_config_ctx_new(link_config_ctx
**ret
) {
120 _cleanup_(link_config_ctx_freep
) link_config_ctx
*ctx
= NULL
;
125 ctx
= new0(link_config_ctx
, 1);
129 LIST_HEAD_INIT(ctx
->links
);
131 ctx
->ethtool_fd
= -1;
133 ctx
->enable_name_policy
= true;
141 static int load_link(link_config_ctx
*ctx
, const char *filename
) {
142 _cleanup_(link_config_freep
) link_config
*link
= NULL
;
143 _cleanup_fclose_
FILE *file
= NULL
;
149 file
= fopen(filename
, "re");
157 if (null_or_empty_fd(fileno(file
))) {
158 log_debug("Skipping empty file: %s", filename
);
162 link
= new0(link_config
, 1);
166 link
->mac_policy
= _MACPOLICY_INVALID
;
167 link
->wol
= _WOL_INVALID
;
168 link
->duplex
= _DUP_INVALID
;
170 r
= config_parse(NULL
, filename
, file
,
171 "Match\0Link\0Ethernet\0",
172 config_item_perf_lookup
, link_config_gperf_lookup
,
173 false, false, true, link
);
177 log_debug("Parsed configuration file %s", filename
);
179 if (link
->mtu
> UINT_MAX
|| link
->speed
> UINT_MAX
)
182 link
->filename
= strdup(filename
);
184 LIST_PREPEND(links
, ctx
->links
, link
);
190 static bool enable_name_policy(void) {
191 _cleanup_free_
char *line
= NULL
;
192 const char *word
, *state
;
196 r
= proc_cmdline(&line
);
198 log_warning_errno(r
, "Failed to read /proc/cmdline, ignoring: %m");
202 FOREACH_WORD_QUOTED(word
, l
, line
, state
)
203 if (strneq(word
, "net.ifnames=0", l
))
209 int link_config_load(link_config_ctx
*ctx
) {
211 _cleanup_strv_free_
char **files
;
214 link_configs_free(ctx
);
216 if (!enable_name_policy()) {
217 ctx
->enable_name_policy
= false;
218 log_info("Network interface NamePolicy= disabled on kernel command line, ignoring.");
221 /* update timestamp */
222 paths_check_timestamp(link_dirs
, &ctx
->link_dirs_ts_usec
, true);
224 r
= conf_files_list_strv(&files
, ".link", NULL
, link_dirs
);
226 return log_error_errno(r
, "failed to enumerate link files: %m");
228 STRV_FOREACH_BACKWARDS(f
, files
) {
229 r
= load_link(ctx
, *f
);
237 bool link_config_should_reload(link_config_ctx
*ctx
) {
238 return paths_check_timestamp(link_dirs
, &ctx
->link_dirs_ts_usec
, false);
241 int link_config_get(link_config_ctx
*ctx
, struct udev_device
*device
,
249 LIST_FOREACH(links
, link
, ctx
->links
) {
250 const char* attr_value
;
252 attr_value
= udev_device_get_sysattr_value(device
, "address");
254 if (net_match_config(link
->match_mac
, link
->match_path
, link
->match_driver
,
255 link
->match_type
, link
->match_name
, link
->match_host
,
256 link
->match_virt
, link
->match_kernel
, link
->match_arch
,
257 attr_value
? ether_aton(attr_value
) : NULL
,
258 udev_device_get_property_value(device
, "ID_PATH"),
259 udev_device_get_driver(udev_device_get_parent(device
)),
260 udev_device_get_property_value(device
, "ID_NET_DRIVER"),
261 udev_device_get_devtype(device
),
262 udev_device_get_sysname(device
))) {
263 if (link
->match_name
) {
264 unsigned char name_assign_type
= NET_NAME_UNKNOWN
;
266 attr_value
= udev_device_get_sysattr_value(device
, "name_assign_type");
268 (void) safe_atou8(attr_value
, &name_assign_type
);
270 if (name_assign_type
== NET_NAME_ENUM
) {
271 log_warning("Config file %s applies to device based on potentially unpredictable interface name '%s'",
272 link
->filename
, udev_device_get_sysname(device
));
276 } else if (name_assign_type
== NET_NAME_RENAMED
) {
277 log_warning("Config file %s matches device based on renamed interface name '%s', ignoring",
278 link
->filename
, udev_device_get_sysname(device
));
284 log_debug("Config file %s applies to device %s",
285 link
->filename
, udev_device_get_sysname(device
));
298 static bool mac_is_random(struct udev_device
*device
) {
303 /* if we can't get the assign type, assume it is not random */
304 s
= udev_device_get_sysattr_value(device
, "addr_assign_type");
308 r
= safe_atou(s
, &type
);
312 return type
== NET_ADDR_RANDOM
;
315 static bool should_rename(struct udev_device
*device
, bool respect_predictable
) {
320 /* if we can't get the assgin type, assume we should rename */
321 s
= udev_device_get_sysattr_value(device
, "name_assign_type");
325 r
= safe_atou(s
, &type
);
331 case NET_NAME_RENAMED
:
332 /* these were already named by userspace, do not touch again */
334 case NET_NAME_PREDICTABLE
:
335 /* the kernel claims to have given a predictable name */
336 if (respect_predictable
)
341 /* the name is known to be bad, or of an unknown type */
346 static int get_mac(struct udev_device
*device
, bool want_random
,
347 struct ether_addr
*mac
) {
351 random_bytes(mac
->ether_addr_octet
, ETH_ALEN
);
355 r
= net_get_unique_predictable_data(device
, result
);
359 assert_cc(ETH_ALEN
<= sizeof(result
));
360 memcpy(mac
->ether_addr_octet
, result
, ETH_ALEN
);
363 /* see eth_random_addr in the kernel */
364 mac
->ether_addr_octet
[0] &= 0xfe; /* clear multicast bit */
365 mac
->ether_addr_octet
[0] |= 0x02; /* set local assignment bit (IEEE802) */
370 int link_config_apply(link_config_ctx
*ctx
, link_config
*config
,
371 struct udev_device
*device
, const char **name
) {
372 const char *old_name
;
373 const char *new_name
= NULL
;
374 struct ether_addr generated_mac
;
375 struct ether_addr
*mac
= NULL
;
376 bool respect_predictable
= false;
384 old_name
= udev_device_get_sysname(device
);
388 r
= ethtool_set_speed(&ctx
->ethtool_fd
, old_name
, config
->speed
/ 1024, config
->duplex
);
390 log_warning_errno(r
, "Could not set speed or duplex of %s to %zu Mbps (%s): %m",
391 old_name
, config
->speed
/ 1024,
392 duplex_to_string(config
->duplex
));
394 r
= ethtool_set_wol(&ctx
->ethtool_fd
, old_name
, config
->wol
);
396 log_warning_errno(r
, "Could not set WakeOnLan of %s to %s: %m",
397 old_name
, wol_to_string(config
->wol
));
399 ifindex
= udev_device_get_ifindex(device
);
401 log_warning("Could not find ifindex");
405 if (ctx
->enable_name_policy
&& config
->name_policy
) {
408 for (policy
= config
->name_policy
;
409 !new_name
&& *policy
!= _NAMEPOLICY_INVALID
; policy
++) {
411 case NAMEPOLICY_KERNEL
:
412 respect_predictable
= true;
414 case NAMEPOLICY_DATABASE
:
415 new_name
= udev_device_get_property_value(device
, "ID_NET_NAME_FROM_DATABASE");
417 case NAMEPOLICY_ONBOARD
:
418 new_name
= udev_device_get_property_value(device
, "ID_NET_NAME_ONBOARD");
420 case NAMEPOLICY_SLOT
:
421 new_name
= udev_device_get_property_value(device
, "ID_NET_NAME_SLOT");
423 case NAMEPOLICY_PATH
:
424 new_name
= udev_device_get_property_value(device
, "ID_NET_NAME_PATH");
427 new_name
= udev_device_get_property_value(device
, "ID_NET_NAME_MAC");
435 if (should_rename(device
, respect_predictable
)) {
436 /* if not set by policy, fall back manually set name */
438 new_name
= config
->name
;
442 switch (config
->mac_policy
) {
443 case MACPOLICY_PERSISTENT
:
444 if (mac_is_random(device
)) {
445 r
= get_mac(device
, false, &generated_mac
);
447 log_warning_errno(r
, "Could not generate persistent MAC address for %s: %m", old_name
);
451 mac
= &generated_mac
;
454 case MACPOLICY_RANDOM
:
455 if (!mac_is_random(device
)) {
456 r
= get_mac(device
, true, &generated_mac
);
458 log_warning_errno(r
, "Could not generate random MAC address for %s: %m", old_name
);
462 mac
= &generated_mac
;
470 r
= rtnl_set_link_properties(&ctx
->rtnl
, ifindex
, config
->alias
, mac
, config
->mtu
);
472 return log_warning_errno(r
, "Could not set Alias, MACAddress or MTU on %s: %m", old_name
);
479 int link_get_driver(link_config_ctx
*ctx
, struct udev_device
*device
, char **ret
) {
484 name
= udev_device_get_sysname(device
);
488 r
= ethtool_get_driver(&ctx
->ethtool_fd
, name
, &driver
);
496 static const char* const mac_policy_table
[_MACPOLICY_MAX
] = {
497 [MACPOLICY_PERSISTENT
] = "persistent",
498 [MACPOLICY_RANDOM
] = "random",
499 [MACPOLICY_NONE
] = "none"
502 DEFINE_STRING_TABLE_LOOKUP(mac_policy
, MACPolicy
);
503 DEFINE_CONFIG_PARSE_ENUM(config_parse_mac_policy
, mac_policy
, MACPolicy
,
504 "Failed to parse MAC address policy");
506 static const char* const name_policy_table
[_NAMEPOLICY_MAX
] = {
507 [NAMEPOLICY_KERNEL
] = "kernel",
508 [NAMEPOLICY_DATABASE
] = "database",
509 [NAMEPOLICY_ONBOARD
] = "onboard",
510 [NAMEPOLICY_SLOT
] = "slot",
511 [NAMEPOLICY_PATH
] = "path",
512 [NAMEPOLICY_MAC
] = "mac"
515 DEFINE_STRING_TABLE_LOOKUP(name_policy
, NamePolicy
);
516 DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy
, name_policy
, NamePolicy
,
518 "Failed to parse interface name policy");