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>
28 #include "link-config.h"
29 #include "ethtool-util.h"
31 #include "libudev-private.h"
36 #include "path-util.h"
37 #include "conf-parser.h"
38 #include "conf-files.h"
41 #include "rtnl-util.h"
42 #include "network-internal.h"
43 #include "siphash24.h"
45 struct link_config_ctx {
46 LIST_HEAD(link_config, links);
50 bool enable_name_policy;
54 usec_t link_dirs_ts_usec;
57 static const char* const link_dirs[] = {
58 "/etc/systemd/network",
59 "/run/systemd/network",
60 "/usr/lib/systemd/network",
62 "/lib/systemd/network",
66 DEFINE_TRIVIAL_CLEANUP_FUNC(link_config_ctx*, link_config_ctx_free);
67 #define _cleanup_link_config_ctx_free_ _cleanup_(link_config_ctx_freep)
69 int link_config_ctx_new(link_config_ctx **ret) {
70 _cleanup_link_config_ctx_free_ link_config_ctx *ctx = NULL;
75 ctx = new0(link_config_ctx, 1);
79 LIST_HEAD_INIT(ctx->links);
83 ctx->enable_name_policy = true;
91 static int link_config_ctx_connect(link_config_ctx *ctx) {
94 if (ctx->ethtool_fd == -1) {
95 r = ethtool_connect(&ctx->ethtool_fd);
97 log_warning("link_config: could not connect to ethtool: %s",
104 r = sd_rtnl_open(&ctx->rtnl, 0);
106 log_warning("link_config: could not connect to rtnl: %s",
115 static void link_configs_free(link_config_ctx *ctx) {
116 link_config *link, *link_next;
121 LIST_FOREACH_SAFE(links, link, link_next, ctx->links) {
122 free(link->filename);
123 free(link->match_path);
124 free(link->match_driver);
125 free(link->match_type);
126 free(link->description);
128 free(link->name_policy);
134 void link_config_ctx_free(link_config_ctx *ctx) {
138 safe_close(ctx->ethtool_fd);
140 sd_rtnl_unref(ctx->rtnl);
142 link_configs_free(ctx);
149 static int load_link(link_config_ctx *ctx, const char *filename) {
150 _cleanup_free_ link_config *link = NULL;
151 _cleanup_fclose_ FILE *file = NULL;
157 file = fopen(filename, "re");
165 if (null_or_empty_fd(fileno(file))) {
166 log_debug("Skipping empty file: %s", filename);
170 link = new0(link_config, 1);
174 link->mac_policy = _MACPOLICY_INVALID;
175 link->wol = _WOL_INVALID;
176 link->duplex = _DUP_INVALID;
178 r = config_parse(NULL, filename, file,
179 "Match\0Link\0Ethernet\0",
180 config_item_perf_lookup, link_config_gperf_lookup,
181 false, false, true, link);
185 log_debug("Parsed configuration file %s", filename);
187 link->filename = strdup(filename);
189 LIST_PREPEND(links, ctx->links, link);
195 static bool enable_name_policy(void) {
196 _cleanup_free_ char *line = NULL;
197 const char *word, *state;
201 r = proc_cmdline(&line);
203 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
207 FOREACH_WORD_QUOTED(word, l, line, state)
208 if (strneq(word, "net.ifnames=0", l))
214 int link_config_load(link_config_ctx *ctx) {
216 _cleanup_strv_free_ char **files;
219 link_configs_free(ctx);
221 if (!enable_name_policy()) {
222 ctx->enable_name_policy = false;
223 log_info("Network interface NamePolicy= disabled on kernel commandline, ignoring.");
226 /* update timestamp */
227 paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, true);
229 r = conf_files_list_strv(&files, ".link", NULL, link_dirs);
231 log_error("failed to enumerate link files: %s", strerror(-r));
235 STRV_FOREACH_BACKWARDS(f, files) {
236 r = load_link(ctx, *f);
244 bool link_config_should_reload(link_config_ctx *ctx) {
245 return paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, false);
248 int link_config_get(link_config_ctx *ctx, struct udev_device *device, link_config **ret) {
251 LIST_FOREACH(links, link, ctx->links) {
253 if (net_match_config(link->match_mac, link->match_path, link->match_driver,
254 link->match_type, NULL, link->match_host,
255 link->match_virt, link->match_kernel, link->match_arch,
256 ether_aton(udev_device_get_sysattr_value(device, "address")),
257 udev_device_get_property_value(device, "ID_PATH"),
258 udev_device_get_driver(udev_device_get_parent(device)),
259 udev_device_get_property_value(device, "ID_NET_DRIVER"),
260 udev_device_get_devtype(device),
262 log_debug("Config file %s applies to device %s",
264 udev_device_get_sysname(device));
275 static bool mac_is_random(struct udev_device *device) {
280 s = udev_device_get_sysattr_value(device, "addr_assign_type");
282 return false; /* if we don't know, assume it is not random */
283 r = safe_atou(s, &type);
287 return type == NET_ADDR_RANDOM;
290 static bool should_rename(struct udev_device *device, bool respect_predictable) {
295 s = udev_device_get_sysattr_value(device, "name_assign_type");
297 return true; /* if we don't know, assume we should rename */
298 r = safe_atou(s, &type);
304 case NET_NAME_RENAMED:
305 return false; /* these were already named by userspace, do not touch again */
306 case NET_NAME_PREDICTABLE:
307 if (respect_predictable)
308 return false; /* the kernel claims to have given a predictable name */
312 return true; /* the name is known to be bad, or of an unknown type */
316 static int get_mac(struct udev_device *device, bool want_random, struct ether_addr *mac) {
320 random_bytes(mac->ether_addr_octet, ETH_ALEN);
324 r = net_get_unique_predictable_data(device, result);
328 assert_cc(ETH_ALEN <= sizeof(result));
329 memcpy(mac->ether_addr_octet, result, ETH_ALEN);
332 /* see eth_random_addr in the kernel */
333 mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */
334 mac->ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */
339 int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_device *device, const char **name) {
340 const char *old_name;
341 const char *new_name = NULL;
342 struct ether_addr generated_mac;
343 struct ether_addr *mac = NULL;
344 bool respect_predictable = false;
352 r = link_config_ctx_connect(ctx);
356 old_name = udev_device_get_sysname(device);
360 r = ethtool_set_speed(ctx->ethtool_fd, old_name, config->speed / 1024, config->duplex);
362 log_warning("Could not set speed or duplex of %s to %u Mbps (%s): %s",
363 old_name, config->speed / 1024, duplex_to_string(config->duplex),
366 r = ethtool_set_wol(ctx->ethtool_fd, old_name, config->wol);
368 log_warning("Could not set WakeOnLan of %s to %s: %s",
369 old_name, wol_to_string(config->wol), strerror(-r));
371 ifindex = udev_device_get_ifindex(device);
373 log_warning("Could not find ifindex");
377 if (ctx->enable_name_policy && config->name_policy) {
380 for (policy = config->name_policy; !respect_predictable && !new_name &&
381 *policy != _NAMEPOLICY_INVALID; policy++) {
383 case NAMEPOLICY_KERNEL:
384 respect_predictable = true;
386 case NAMEPOLICY_DATABASE:
387 new_name = udev_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE");
389 case NAMEPOLICY_ONBOARD:
390 new_name = udev_device_get_property_value(device, "ID_NET_NAME_ONBOARD");
392 case NAMEPOLICY_SLOT:
393 new_name = udev_device_get_property_value(device, "ID_NET_NAME_SLOT");
395 case NAMEPOLICY_PATH:
396 new_name = udev_device_get_property_value(device, "ID_NET_NAME_PATH");
399 new_name = udev_device_get_property_value(device, "ID_NET_NAME_MAC");
407 if (should_rename(device, respect_predictable)) {
409 /* if not set by policy, fall back manually set name */
410 new_name = config->name;
416 switch (config->mac_policy) {
417 case MACPOLICY_PERSISTENT:
418 if (mac_is_random(device)) {
419 r = get_mac(device, false, &generated_mac);
424 mac = &generated_mac;
427 case MACPOLICY_RANDOM:
428 if (!mac_is_random(device)) {
429 r = get_mac(device, true, &generated_mac);
434 mac = &generated_mac;
441 r = rtnl_set_link_properties(ctx->rtnl, ifindex, config->alias, mac, config->mtu);
443 log_warning("Could not set Alias, MACAddress or MTU on %s: %s", old_name, strerror(-r));
450 int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret) {
455 r = link_config_ctx_connect(ctx);
459 name = udev_device_get_sysname(device);
463 r = ethtool_get_driver(ctx->ethtool_fd, name, &driver);
471 static const char* const mac_policy_table[_MACPOLICY_MAX] = {
472 [MACPOLICY_PERSISTENT] = "persistent",
473 [MACPOLICY_RANDOM] = "random"
476 DEFINE_STRING_TABLE_LOOKUP(mac_policy, MACPolicy);
477 DEFINE_CONFIG_PARSE_ENUM(config_parse_mac_policy, mac_policy, MACPolicy, "Failed to parse MAC address policy");
479 static const char* const name_policy_table[_NAMEPOLICY_MAX] = {
480 [NAMEPOLICY_KERNEL] = "kernel",
481 [NAMEPOLICY_DATABASE] = "database",
482 [NAMEPOLICY_ONBOARD] = "onboard",
483 [NAMEPOLICY_SLOT] = "slot",
484 [NAMEPOLICY_PATH] = "path",
485 [NAMEPOLICY_MAC] = "mac"
488 DEFINE_STRING_TABLE_LOOKUP(name_policy, NamePolicy);
489 DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy, _NAMEPOLICY_INVALID, "Failed to parse interface name policy");