diff options
Diffstat (limited to 'src/udev/net')
-rw-r--r-- | src/udev/net/.gitignore | 1 | ||||
l--------- | src/udev/net/Makefile | 1 | ||||
-rw-r--r-- | src/udev/net/ethtool-util.c | 325 | ||||
-rw-r--r-- | src/udev/net/ethtool-util.h | 65 | ||||
-rw-r--r-- | src/udev/net/link-config-gperf.gperf | 42 | ||||
-rw-r--r-- | src/udev/net/link-config.c | 517 | ||||
-rw-r--r-- | src/udev/net/link-config.h | 99 |
7 files changed, 0 insertions, 1050 deletions
diff --git a/src/udev/net/.gitignore b/src/udev/net/.gitignore deleted file mode 100644 index 9ca85bacc9..0000000000 --- a/src/udev/net/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/link-config-gperf.c diff --git a/src/udev/net/Makefile b/src/udev/net/Makefile deleted file mode 120000 index 94aaae2c4d..0000000000 --- a/src/udev/net/Makefile +++ /dev/null @@ -1 +0,0 @@ -../../Makefile
\ No newline at end of file diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c deleted file mode 100644 index 708a665576..0000000000 --- a/src/udev/net/ethtool-util.c +++ /dev/null @@ -1,325 +0,0 @@ -/*** - This file is part of systemd. - - Copyright (C) 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <net/if.h> -#include <sys/ioctl.h> -#include <linux/ethtool.h> -#include <linux/sockios.h> - -#include "conf-parser.h" -#include "ethtool-util.h" -#include "log.h" -#include "socket-util.h" -#include "string-table.h" -#include "strxcpyx.h" -#include "util.h" - -static const char* const duplex_table[_DUP_MAX] = { - [DUP_FULL] = "full", - [DUP_HALF] = "half" -}; - -DEFINE_STRING_TABLE_LOOKUP(duplex, Duplex); -DEFINE_CONFIG_PARSE_ENUM(config_parse_duplex, duplex, Duplex, "Failed to parse duplex setting"); - -static const char* const wol_table[_WOL_MAX] = { - [WOL_PHY] = "phy", - [WOL_MAGIC] = "magic", - [WOL_OFF] = "off" -}; - -DEFINE_STRING_TABLE_LOOKUP(wol, WakeOnLan); -DEFINE_CONFIG_PARSE_ENUM(config_parse_wol, wol, WakeOnLan, "Failed to parse WakeOnLan setting"); - -static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = { - [NET_DEV_FEAT_GSO] = "tx-generic-segmentation", - [NET_DEV_FEAT_GRO] = "rx-gro", - [NET_DEV_FEAT_LRO] = "rx-lro", - [NET_DEV_FEAT_TSO] = "tx-tcp-segmentation", - [NET_DEV_FEAT_UFO] = "tx-udp-fragmentation", -}; - -int ethtool_connect(int *ret) { - int fd; - - assert_return(ret, -EINVAL); - - fd = socket_ioctl_fd(); - if (fd < 0) - return fd; - *ret = fd; - - return 0; -} - -int ethtool_get_driver(int *fd, const char *ifname, char **ret) { - struct ethtool_drvinfo ecmd = { - .cmd = ETHTOOL_GDRVINFO - }; - struct ifreq ifr = { - .ifr_data = (void*) &ecmd - }; - char *d; - int r; - - if (*fd < 0) { - r = ethtool_connect(fd); - if (r < 0) - return log_warning_errno(r, "link_config: could not connect to ethtool: %m"); - } - - strscpy(ifr.ifr_name, IFNAMSIZ, ifname); - - r = ioctl(*fd, SIOCETHTOOL, &ifr); - if (r < 0) - return -errno; - - d = strdup(ecmd.driver); - if (!d) - return -ENOMEM; - - *ret = d; - return 0; -} - -int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex) { - struct ethtool_cmd ecmd = { - .cmd = ETHTOOL_GSET - }; - struct ifreq ifr = { - .ifr_data = (void*) &ecmd - }; - bool need_update = false; - int r; - - if (speed == 0 && duplex == _DUP_INVALID) - return 0; - - if (*fd < 0) { - r = ethtool_connect(fd); - if (r < 0) - return log_warning_errno(r, "link_config: could not connect to ethtool: %m"); - } - - strscpy(ifr.ifr_name, IFNAMSIZ, ifname); - - r = ioctl(*fd, SIOCETHTOOL, &ifr); - if (r < 0) - return -errno; - - if (ethtool_cmd_speed(&ecmd) != speed) { - ethtool_cmd_speed_set(&ecmd, speed); - need_update = true; - } - - switch (duplex) { - case DUP_HALF: - if (ecmd.duplex != DUPLEX_HALF) { - ecmd.duplex = DUPLEX_HALF; - need_update = true; - } - break; - case DUP_FULL: - if (ecmd.duplex != DUPLEX_FULL) { - ecmd.duplex = DUPLEX_FULL; - need_update = true; - } - break; - default: - break; - } - - if (need_update) { - ecmd.cmd = ETHTOOL_SSET; - - r = ioctl(*fd, SIOCETHTOOL, &ifr); - if (r < 0) - return -errno; - } - - return 0; -} - -int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol) { - struct ethtool_wolinfo ecmd = { - .cmd = ETHTOOL_GWOL - }; - struct ifreq ifr = { - .ifr_data = (void*) &ecmd - }; - bool need_update = false; - int r; - - if (wol == _WOL_INVALID) - return 0; - - if (*fd < 0) { - r = ethtool_connect(fd); - if (r < 0) - return log_warning_errno(r, "link_config: could not connect to ethtool: %m"); - } - - strscpy(ifr.ifr_name, IFNAMSIZ, ifname); - - r = ioctl(*fd, SIOCETHTOOL, &ifr); - if (r < 0) - return -errno; - - switch (wol) { - case WOL_PHY: - if (ecmd.wolopts != WAKE_PHY) { - ecmd.wolopts = WAKE_PHY; - need_update = true; - } - break; - case WOL_MAGIC: - if (ecmd.wolopts != WAKE_MAGIC) { - ecmd.wolopts = WAKE_MAGIC; - need_update = true; - } - break; - case WOL_OFF: - if (ecmd.wolopts != 0) { - ecmd.wolopts = 0; - need_update = true; - } - break; - default: - break; - } - - if (need_update) { - ecmd.cmd = ETHTOOL_SWOL; - - r = ioctl(*fd, SIOCETHTOOL, &ifr); - if (r < 0) - return -errno; - } - - return 0; -} - -static int ethtool_get_stringset(int *fd, struct ifreq *ifr, int stringset_id, struct ethtool_gstrings **gstrings) { - _cleanup_free_ struct ethtool_gstrings *strings = NULL; - struct { - struct ethtool_sset_info info; - uint32_t space; - } buffer = { - .info = { - .cmd = ETHTOOL_GSSET_INFO, - .sset_mask = UINT64_C(1) << stringset_id, - }, - }; - unsigned len; - int r; - - ifr->ifr_data = (void *) &buffer.info; - - r = ioctl(*fd, SIOCETHTOOL, ifr); - if (r < 0) - return -errno; - - if (!buffer.info.sset_mask) - return -EINVAL; - - len = buffer.info.data[0]; - - strings = malloc0(sizeof(struct ethtool_gstrings) + len * ETH_GSTRING_LEN); - if (!strings) - return -ENOMEM; - - strings->cmd = ETHTOOL_GSTRINGS; - strings->string_set = stringset_id; - strings->len = len; - - ifr->ifr_data = (void *) strings; - - r = ioctl(*fd, SIOCETHTOOL, ifr); - if (r < 0) - return -errno; - - *gstrings = strings; - strings = NULL; - - return 0; -} - -static int find_feature_index(struct ethtool_gstrings *strings, const char *feature) { - unsigned i; - - for (i = 0; i < strings->len; i++) { - if (streq((char *) &strings->data[i * ETH_GSTRING_LEN], feature)) - return i; - } - - return -1; -} - -int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features) { - _cleanup_free_ struct ethtool_gstrings *strings = NULL; - struct ethtool_sfeatures *sfeatures; - int block, bit, i, r; - struct ifreq ifr = {}; - - if (*fd < 0) { - r = ethtool_connect(fd); - if (r < 0) - return log_warning_errno(r, "link_config: could not connect to ethtool: %m"); - } - - strscpy(ifr.ifr_name, IFNAMSIZ, ifname); - - r = ethtool_get_stringset(fd, &ifr, ETH_SS_FEATURES, &strings); - if (r < 0) - return log_warning_errno(r, "link_config: could not get ethtool features for %s", ifname); - - sfeatures = alloca0(sizeof(struct ethtool_gstrings) + DIV_ROUND_UP(strings->len, 32U) * sizeof(sfeatures->features[0])); - sfeatures->cmd = ETHTOOL_SFEATURES; - sfeatures->size = DIV_ROUND_UP(strings->len, 32U); - - for (i = 0; i < _NET_DEV_FEAT_MAX; i++) { - - if (features[i] != -1) { - - r = find_feature_index(strings, netdev_feature_table[i]); - if (r < 0) { - log_warning_errno(r, "link_config: could not find feature: %s", netdev_feature_table[i]); - continue; - } - - block = r / 32; - bit = r % 32; - - sfeatures->features[block].valid |= 1 << bit; - - if (features[i]) - sfeatures->features[block].requested |= 1 << bit; - else - sfeatures->features[block].requested &= ~(1 << bit); - } - } - - ifr.ifr_data = (void *) sfeatures; - - r = ioctl(*fd, SIOCETHTOOL, &ifr); - if (r < 0) - return log_warning_errno(r, "link_config: could not set ethtool features for %s", ifname); - - return 0; -} diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h deleted file mode 100644 index 0744164653..0000000000 --- a/src/udev/net/ethtool-util.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once - -/*** - This file is part of systemd. - - Copyright (C) 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <macro.h> - -/* we can't use DUPLEX_ prefix, as it - * clashes with <linux/ethtool.h> */ -typedef enum Duplex { - DUP_FULL, - DUP_HALF, - _DUP_MAX, - _DUP_INVALID = -1 -} Duplex; - -typedef enum WakeOnLan { - WOL_PHY, - WOL_MAGIC, - WOL_OFF, - _WOL_MAX, - _WOL_INVALID = -1 -} WakeOnLan; - -typedef enum NetDevFeature { - NET_DEV_FEAT_GSO, - NET_DEV_FEAT_GRO, - NET_DEV_FEAT_LRO, - NET_DEV_FEAT_TSO, - NET_DEV_FEAT_UFO, - _NET_DEV_FEAT_MAX, - _NET_DEV_FEAT_INVALID = -1 -} NetDevFeature; - -int ethtool_connect(int *ret); - -int ethtool_get_driver(int *fd, const char *ifname, char **ret); -int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex); -int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol); -int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features); - -const char *duplex_to_string(Duplex d) _const_; -Duplex duplex_from_string(const char *d) _pure_; - -const char *wol_to_string(WakeOnLan wol) _const_; -WakeOnLan wol_from_string(const char *wol) _pure_; - -int config_parse_duplex(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_wol(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf deleted file mode 100644 index f8b85cbd13..0000000000 --- a/src/udev/net/link-config-gperf.gperf +++ /dev/null @@ -1,42 +0,0 @@ -%{ -#include <stddef.h> -#include "conf-parser.h" -#include "network-internal.h" -#include "link-config.h" -#include "ethtool-util.h" -%} -struct ConfigPerfItem; -%null_strings -%language=ANSI-C -%define slot-name section_and_lvalue -%define hash-function-name link_config_gperf_hash -%define lookup-function-name link_config_gperf_lookup -%readonly-tables -%omit-struct-type -%struct-type -%includes -%% -Match.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, match_mac) -Match.OriginalName, config_parse_ifnames, 0, offsetof(link_config, match_name) -Match.Path, config_parse_strv, 0, offsetof(link_config, match_path) -Match.Driver, config_parse_strv, 0, offsetof(link_config, match_driver) -Match.Type, config_parse_strv, 0, offsetof(link_config, match_type) -Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(link_config, match_host) -Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(link_config, match_virt) -Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, match_kernel) -Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(link_config, match_arch) -Link.Description, config_parse_string, 0, offsetof(link_config, description) -Link.MACAddressPolicy, config_parse_mac_policy, 0, offsetof(link_config, mac_policy) -Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac) -Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy) -Link.Name, config_parse_ifname, 0, offsetof(link_config, name) -Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias) -Link.MTUBytes, config_parse_iec_size, 0, offsetof(link_config, mtu) -Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed) -Link.Duplex, config_parse_duplex, 0, offsetof(link_config, duplex) -Link.WakeOnLan, config_parse_wol, 0, offsetof(link_config, wol) -Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GSO]) -Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_TSO]) -Link.UDPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_UFO]) -Link.GenericReceiveOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GRO]) -Link.LargeReceiveOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_LRO]) diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c deleted file mode 100644 index ece9248c2a..0000000000 --- a/src/udev/net/link-config.c +++ /dev/null @@ -1,517 +0,0 @@ -/*** - This file is part of systemd. - - Copyright (C) 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <netinet/ether.h> - -#include "sd-netlink.h" - -#include "alloc-util.h" -#include "conf-files.h" -#include "conf-parser.h" -#include "ethtool-util.h" -#include "fd-util.h" -#include "libudev-private.h" -#include "link-config.h" -#include "log.h" -#include "missing.h" -#include "netlink-util.h" -#include "network-internal.h" -#include "parse-util.h" -#include "path-util.h" -#include "proc-cmdline.h" -#include "random-util.h" -#include "stat-util.h" -#include "string-table.h" -#include "string-util.h" -#include "strv.h" -#include "util.h" - -struct link_config_ctx { - LIST_HEAD(link_config, links); - - int ethtool_fd; - - bool enable_name_policy; - - sd_netlink *rtnl; - - usec_t link_dirs_ts_usec; -}; - -static const char* const link_dirs[] = { - "/etc/systemd/network", - "/run/systemd/network", - "/usr/lib/systemd/network", -#ifdef HAVE_SPLIT_USR - "/lib/systemd/network", -#endif - NULL}; - -static void link_config_free(link_config *link) { - if (!link) - return; - - free(link->filename); - - free(link->match_mac); - strv_free(link->match_path); - strv_free(link->match_driver); - strv_free(link->match_type); - free(link->match_name); - free(link->match_host); - free(link->match_virt); - free(link->match_kernel); - free(link->match_arch); - - free(link->description); - free(link->mac); - free(link->name_policy); - free(link->name); - free(link->alias); - - free(link); -} - -DEFINE_TRIVIAL_CLEANUP_FUNC(link_config*, link_config_free); - -static void link_configs_free(link_config_ctx *ctx) { - link_config *link, *link_next; - - if (!ctx) - return; - - LIST_FOREACH_SAFE(links, link, link_next, ctx->links) - link_config_free(link); -} - -void link_config_ctx_free(link_config_ctx *ctx) { - if (!ctx) - return; - - safe_close(ctx->ethtool_fd); - - sd_netlink_unref(ctx->rtnl); - - link_configs_free(ctx); - - free(ctx); - - return; -} - -DEFINE_TRIVIAL_CLEANUP_FUNC(link_config_ctx*, link_config_ctx_free); - -int link_config_ctx_new(link_config_ctx **ret) { - _cleanup_(link_config_ctx_freep) link_config_ctx *ctx = NULL; - - if (!ret) - return -EINVAL; - - ctx = new0(link_config_ctx, 1); - if (!ctx) - return -ENOMEM; - - LIST_HEAD_INIT(ctx->links); - - ctx->ethtool_fd = -1; - - ctx->enable_name_policy = true; - - *ret = ctx; - ctx = NULL; - - return 0; -} - -static int load_link(link_config_ctx *ctx, const char *filename) { - _cleanup_(link_config_freep) link_config *link = NULL; - _cleanup_fclose_ FILE *file = NULL; - int r; - - assert(ctx); - assert(filename); - - file = fopen(filename, "re"); - if (!file) { - if (errno == ENOENT) - return 0; - else - return -errno; - } - - if (null_or_empty_fd(fileno(file))) { - log_debug("Skipping empty file: %s", filename); - return 0; - } - - link = new0(link_config, 1); - if (!link) - return log_oom(); - - link->mac_policy = _MACPOLICY_INVALID; - link->wol = _WOL_INVALID; - link->duplex = _DUP_INVALID; - - memset(&link->features, -1, _NET_DEV_FEAT_MAX); - - r = config_parse(NULL, filename, file, - "Match\0Link\0Ethernet\0", - config_item_perf_lookup, link_config_gperf_lookup, - false, false, true, link); - if (r < 0) - return r; - else - log_debug("Parsed configuration file %s", filename); - - if (link->mtu > UINT_MAX || link->speed > UINT_MAX) - return -ERANGE; - - link->filename = strdup(filename); - - LIST_PREPEND(links, ctx->links, link); - link = NULL; - - return 0; -} - -static bool enable_name_policy(void) { - _cleanup_free_ char *value = NULL; - int r; - - r = get_proc_cmdline_key("net.ifnames=", &value); - if (r > 0 && streq(value, "0")) - return false; - - return true; -} - -int link_config_load(link_config_ctx *ctx) { - int r; - _cleanup_strv_free_ char **files; - char **f; - - link_configs_free(ctx); - - if (!enable_name_policy()) { - ctx->enable_name_policy = false; - log_info("Network interface NamePolicy= disabled on kernel command line, ignoring."); - } - - /* update timestamp */ - paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, true); - - r = conf_files_list_strv(&files, ".link", NULL, link_dirs); - if (r < 0) - return log_error_errno(r, "failed to enumerate link files: %m"); - - STRV_FOREACH_BACKWARDS(f, files) { - r = load_link(ctx, *f); - if (r < 0) - return r; - } - - return 0; -} - -bool link_config_should_reload(link_config_ctx *ctx) { - return paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, false); -} - -int link_config_get(link_config_ctx *ctx, struct udev_device *device, - link_config **ret) { - link_config *link; - - assert(ctx); - assert(device); - assert(ret); - - LIST_FOREACH(links, link, ctx->links) { - const char* attr_value; - - attr_value = udev_device_get_sysattr_value(device, "address"); - - if (net_match_config(link->match_mac, link->match_path, link->match_driver, - link->match_type, link->match_name, link->match_host, - link->match_virt, link->match_kernel, link->match_arch, - attr_value ? ether_aton(attr_value) : NULL, - udev_device_get_property_value(device, "ID_PATH"), - udev_device_get_driver(udev_device_get_parent(device)), - udev_device_get_property_value(device, "ID_NET_DRIVER"), - udev_device_get_devtype(device), - udev_device_get_sysname(device))) { - if (link->match_name) { - unsigned char name_assign_type = NET_NAME_UNKNOWN; - - attr_value = udev_device_get_sysattr_value(device, "name_assign_type"); - if (attr_value) - (void) safe_atou8(attr_value, &name_assign_type); - - if (name_assign_type == NET_NAME_ENUM) { - log_warning("Config file %s applies to device based on potentially unpredictable interface name '%s'", - link->filename, udev_device_get_sysname(device)); - *ret = link; - - return 0; - } else if (name_assign_type == NET_NAME_RENAMED) { - log_warning("Config file %s matches device based on renamed interface name '%s', ignoring", - link->filename, udev_device_get_sysname(device)); - - continue; - } - } - - log_debug("Config file %s applies to device %s", - link->filename, udev_device_get_sysname(device)); - - *ret = link; - - return 0; - } - } - - *ret = NULL; - - return -ENOENT; -} - -static bool mac_is_random(struct udev_device *device) { - const char *s; - unsigned type; - int r; - - /* if we can't get the assign type, assume it is not random */ - s = udev_device_get_sysattr_value(device, "addr_assign_type"); - if (!s) - return false; - - r = safe_atou(s, &type); - if (r < 0) - return false; - - return type == NET_ADDR_RANDOM; -} - -static bool should_rename(struct udev_device *device, bool respect_predictable) { - const char *s; - unsigned type; - int r; - - /* if we can't get the assgin type, assume we should rename */ - s = udev_device_get_sysattr_value(device, "name_assign_type"); - if (!s) - return true; - - r = safe_atou(s, &type); - if (r < 0) - return true; - - switch (type) { - case NET_NAME_USER: - case NET_NAME_RENAMED: - /* these were already named by userspace, do not touch again */ - return false; - case NET_NAME_PREDICTABLE: - /* the kernel claims to have given a predictable name */ - if (respect_predictable) - return false; - /* fall through */ - case NET_NAME_ENUM: - default: - /* the name is known to be bad, or of an unknown type */ - return true; - } -} - -static int get_mac(struct udev_device *device, bool want_random, - struct ether_addr *mac) { - int r; - - if (want_random) - random_bytes(mac->ether_addr_octet, ETH_ALEN); - else { - uint64_t result; - - r = net_get_unique_predictable_data(device, &result); - if (r < 0) - return r; - - assert_cc(ETH_ALEN <= sizeof(result)); - memcpy(mac->ether_addr_octet, &result, ETH_ALEN); - } - - /* see eth_random_addr in the kernel */ - mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */ - mac->ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */ - - return 0; -} - -int link_config_apply(link_config_ctx *ctx, link_config *config, - struct udev_device *device, const char **name) { - const char *old_name; - const char *new_name = NULL; - struct ether_addr generated_mac; - struct ether_addr *mac = NULL; - bool respect_predictable = false; - int r, ifindex; - - assert(ctx); - assert(config); - assert(device); - assert(name); - - old_name = udev_device_get_sysname(device); - if (!old_name) - return -EINVAL; - - r = ethtool_set_speed(&ctx->ethtool_fd, old_name, config->speed / 1024, config->duplex); - if (r < 0) - log_warning_errno(r, "Could not set speed or duplex of %s to %zu Mbps (%s): %m", - old_name, config->speed / 1024, - duplex_to_string(config->duplex)); - - r = ethtool_set_wol(&ctx->ethtool_fd, old_name, config->wol); - if (r < 0) - log_warning_errno(r, "Could not set WakeOnLan of %s to %s: %m", - old_name, wol_to_string(config->wol)); - - r = ethtool_set_features(&ctx->ethtool_fd, old_name, config->features); - if (r < 0) - log_warning_errno(r, "Could not set offload features of %s: %m", old_name); - - ifindex = udev_device_get_ifindex(device); - if (ifindex <= 0) { - log_warning("Could not find ifindex"); - return -ENODEV; - } - - if (ctx->enable_name_policy && config->name_policy) { - NamePolicy *policy; - - for (policy = config->name_policy; - !new_name && *policy != _NAMEPOLICY_INVALID; policy++) { - switch (*policy) { - case NAMEPOLICY_KERNEL: - respect_predictable = true; - break; - case NAMEPOLICY_DATABASE: - new_name = udev_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE"); - break; - case NAMEPOLICY_ONBOARD: - new_name = udev_device_get_property_value(device, "ID_NET_NAME_ONBOARD"); - break; - case NAMEPOLICY_SLOT: - new_name = udev_device_get_property_value(device, "ID_NET_NAME_SLOT"); - break; - case NAMEPOLICY_PATH: - new_name = udev_device_get_property_value(device, "ID_NET_NAME_PATH"); - break; - case NAMEPOLICY_MAC: - new_name = udev_device_get_property_value(device, "ID_NET_NAME_MAC"); - break; - default: - break; - } - } - } - - if (should_rename(device, respect_predictable)) { - /* if not set by policy, fall back manually set name */ - if (!new_name) - new_name = config->name; - } else - new_name = NULL; - - switch (config->mac_policy) { - case MACPOLICY_PERSISTENT: - if (mac_is_random(device)) { - r = get_mac(device, false, &generated_mac); - if (r == -ENOENT) { - log_warning_errno(r, "Could not generate persistent MAC address for %s: %m", old_name); - break; - } else if (r < 0) - return r; - mac = &generated_mac; - } - break; - case MACPOLICY_RANDOM: - if (!mac_is_random(device)) { - r = get_mac(device, true, &generated_mac); - if (r == -ENOENT) { - log_warning_errno(r, "Could not generate random MAC address for %s: %m", old_name); - break; - } else if (r < 0) - return r; - mac = &generated_mac; - } - break; - case MACPOLICY_NONE: - default: - mac = config->mac; - } - - r = rtnl_set_link_properties(&ctx->rtnl, ifindex, config->alias, mac, config->mtu); - if (r < 0) - return log_warning_errno(r, "Could not set Alias, MACAddress or MTU on %s: %m", old_name); - - *name = new_name; - - return 0; -} - -int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret) { - const char *name; - char *driver = NULL; - int r; - - name = udev_device_get_sysname(device); - if (!name) - return -EINVAL; - - r = ethtool_get_driver(&ctx->ethtool_fd, name, &driver); - if (r < 0) - return r; - - *ret = driver; - return 0; -} - -static const char* const mac_policy_table[_MACPOLICY_MAX] = { - [MACPOLICY_PERSISTENT] = "persistent", - [MACPOLICY_RANDOM] = "random", - [MACPOLICY_NONE] = "none" -}; - -DEFINE_STRING_TABLE_LOOKUP(mac_policy, MACPolicy); -DEFINE_CONFIG_PARSE_ENUM(config_parse_mac_policy, mac_policy, MACPolicy, - "Failed to parse MAC address policy"); - -static const char* const name_policy_table[_NAMEPOLICY_MAX] = { - [NAMEPOLICY_KERNEL] = "kernel", - [NAMEPOLICY_DATABASE] = "database", - [NAMEPOLICY_ONBOARD] = "onboard", - [NAMEPOLICY_SLOT] = "slot", - [NAMEPOLICY_PATH] = "path", - [NAMEPOLICY_MAC] = "mac" -}; - -DEFINE_STRING_TABLE_LOOKUP(name_policy, NamePolicy); -DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy, - _NAMEPOLICY_INVALID, - "Failed to parse interface name policy"); diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h deleted file mode 100644 index b0d8ceb76a..0000000000 --- a/src/udev/net/link-config.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -/*** - This file is part of systemd. - - Copyright (C) 2013 Tom Gundersen <teg@jklm.no> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include "libudev.h" - -#include "condition.h" -#include "ethtool-util.h" -#include "list.h" - -typedef struct link_config_ctx link_config_ctx; -typedef struct link_config link_config; - -typedef enum MACPolicy { - MACPOLICY_PERSISTENT, - MACPOLICY_RANDOM, - MACPOLICY_NONE, - _MACPOLICY_MAX, - _MACPOLICY_INVALID = -1 -} MACPolicy; - -typedef enum NamePolicy { - NAMEPOLICY_KERNEL, - NAMEPOLICY_DATABASE, - NAMEPOLICY_ONBOARD, - NAMEPOLICY_SLOT, - NAMEPOLICY_PATH, - NAMEPOLICY_MAC, - _NAMEPOLICY_MAX, - _NAMEPOLICY_INVALID = -1 -} NamePolicy; - -struct link_config { - char *filename; - - struct ether_addr *match_mac; - char **match_path; - char **match_driver; - char **match_type; - char **match_name; - Condition *match_host; - Condition *match_virt; - Condition *match_kernel; - Condition *match_arch; - - char *description; - struct ether_addr *mac; - MACPolicy mac_policy; - NamePolicy *name_policy; - char *name; - char *alias; - size_t mtu; - size_t speed; - Duplex duplex; - WakeOnLan wol; - NetDevFeature features[_NET_DEV_FEAT_MAX]; - - LIST_FIELDS(link_config, links); -}; - -int link_config_ctx_new(link_config_ctx **ret); -void link_config_ctx_free(link_config_ctx *ctx); - -int link_config_load(link_config_ctx *ctx); -bool link_config_should_reload(link_config_ctx *ctx); - -int link_config_get(link_config_ctx *ctx, struct udev_device *device, struct link_config **ret); -int link_config_apply(link_config_ctx *ctx, struct link_config *config, struct udev_device *device, const char **name); - -int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret); - -const char *name_policy_to_string(NamePolicy p) _const_; -NamePolicy name_policy_from_string(const char *p) _pure_; - -const char *mac_policy_to_string(MACPolicy p) _const_; -MACPolicy mac_policy_from_string(const char *p) _pure_; - -/* gperf lookup function */ -const struct ConfigPerfItem* link_config_gperf_lookup(const char *key, GPERF_LEN_TYPE length); - -int config_parse_mac_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_name_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); |