af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen/***
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen This file is part of systemd.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen systemd is free software; you can redistribute it and/or modify it
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen under the terms of the GNU Lesser General Public License as published by
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen (at your option) any later version.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen systemd is distributed in the hope that it will be useful, but
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen Lesser General Public License for more details.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen You should have received a copy of the GNU Lesser General Public License
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen***/
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen#include <netinet/ether.h>
7eb08da4b388b920c8a894b1500c9cc7dc1f31efTom Gundersen#include <linux/netdevice.h>
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "sd-netlink.h"
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "conf-files.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "conf-parser.h"
a501033335ed402c8f7e86fe41a15531ba69abd7Tom Gundersen#include "ethtool-util.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "fd-util.h"
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen#include "libudev-private.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "link-config.h"
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen#include "log.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "missing.h"
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen#include "netlink-util.h"
c6f7c917a1b494d4455800823472227463f87438Tom Gundersen#include "network-internal.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "parse-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "path-util.h"
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering#include "proc-cmdline.h"
3df3e884ae1237ef0d4d23b0e80f4ffda95ac135Ronny Chevalier#include "random-util.h"
8fcde01280adcbd07e8205b91ac52b06305b6208Lennart Poettering#include "stat-util.h"
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering#include "string-table.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "strv.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "util.h"
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersenstruct link_config_ctx {
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen LIST_HEAD(link_config, links);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
a501033335ed402c8f7e86fe41a15531ba69abd7Tom Gundersen int ethtool_fd;
a501033335ed402c8f7e86fe41a15531ba69abd7Tom Gundersen
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen bool enable_name_policy;
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen sd_netlink *rtnl;
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen
97f2d76d4f4dfab8b0629c09926a05a1e5621125Tom Gundersen usec_t link_dirs_ts_usec;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen};
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmekstatic const char* const link_dirs[] = {
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek "/etc/systemd/network",
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek "/run/systemd/network",
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek "/usr/lib/systemd/network",
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek#ifdef HAVE_SPLIT_USR
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek "/lib/systemd/network",
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek#endif
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek NULL};
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersenstatic void link_config_free(link_config *link) {
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen if (!link)
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen return;
5b9d4dc05560ddda89e48b6b39365824b15e1300Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link->filename);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link->match_mac);
43d60b77a83b3185e37c65c4f2649d24c227c7f0Tom Gundersen strv_free(link->match_path);
43d60b77a83b3185e37c65c4f2649d24c227c7f0Tom Gundersen strv_free(link->match_driver);
43d60b77a83b3185e37c65c4f2649d24c227c7f0Tom Gundersen strv_free(link->match_type);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link->match_name);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link->match_host);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link->match_virt);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link->match_kernel);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link->match_arch);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link->description);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link->mac);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link->name_policy);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link->name);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link->alias);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen free(link);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen}
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom GundersenDEFINE_TRIVIAL_CLEANUP_FUNC(link_config*, link_config_free);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersenstatic void link_configs_free(link_config_ctx *ctx) {
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen link_config *link, *link_next;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen if (!ctx)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen LIST_FOREACH_SAFE(links, link, link_next, ctx->links)
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen link_config_free(link);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen}
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersenvoid link_config_ctx_free(link_config_ctx *ctx) {
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen if (!ctx)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering safe_close(ctx->ethtool_fd);
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen sd_netlink_unref(ctx->rtnl);
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen link_configs_free(ctx);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen free(ctx);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen}
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom GundersenDEFINE_TRIVIAL_CLEANUP_FUNC(link_config_ctx*, link_config_ctx_free);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersenint link_config_ctx_new(link_config_ctx **ret) {
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen _cleanup_(link_config_ctx_freep) link_config_ctx *ctx = NULL;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen if (!ret)
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen return -EINVAL;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen ctx = new0(link_config_ctx, 1);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen if (!ctx)
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen return -ENOMEM;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen LIST_HEAD_INIT(ctx->links);
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen ctx->ethtool_fd = -1;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen ctx->enable_name_policy = true;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen *ret = ctx;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen ctx = NULL;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen return 0;
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen}
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersenstatic int load_link(link_config_ctx *ctx, const char *filename) {
9a4b012e43f23516373bf398dd9a458439d19939Tom Gundersen _cleanup_(link_config_freep) link_config *link = NULL;
6e37cd2f4af8928d905203108a4331e375d7127cThomas Hindoe Paaboel Andersen _cleanup_fclose_ FILE *file = NULL;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen int r;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
187dc6e554f2d5b4b5a3bee72c73ff5df6418aa6Thomas Hindoe Paaboel Andersen assert(ctx);
187dc6e554f2d5b4b5a3bee72c73ff5df6418aa6Thomas Hindoe Paaboel Andersen assert(filename);
187dc6e554f2d5b4b5a3bee72c73ff5df6418aa6Thomas Hindoe Paaboel Andersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen file = fopen(filename, "re");
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen if (!file) {
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen if (errno == ENOENT)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return 0;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen else
ecb08ec6a5c52f2d940f3b8147e2a480affd46e1Zbigniew Jędrzejewski-Szmek return -errno;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen }
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
ed88bcfb7c15029f9fc95ee2380759a9eb782d46Zbigniew Jędrzejewski-Szmek if (null_or_empty_fd(fileno(file))) {
ed88bcfb7c15029f9fc95ee2380759a9eb782d46Zbigniew Jędrzejewski-Szmek log_debug("Skipping empty file: %s", filename);
ed88bcfb7c15029f9fc95ee2380759a9eb782d46Zbigniew Jędrzejewski-Szmek return 0;
ed88bcfb7c15029f9fc95ee2380759a9eb782d46Zbigniew Jędrzejewski-Szmek }
ed88bcfb7c15029f9fc95ee2380759a9eb782d46Zbigniew Jędrzejewski-Szmek
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen link = new0(link_config, 1);
ecb08ec6a5c52f2d940f3b8147e2a480affd46e1Zbigniew Jędrzejewski-Szmek if (!link)
ecb08ec6a5c52f2d940f3b8147e2a480affd46e1Zbigniew Jędrzejewski-Szmek return log_oom();
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen link->mac_policy = _MACPOLICY_INVALID;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen link->wol = _WOL_INVALID;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen link->duplex = _DUP_INVALID;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen
e9f3d2d508bfd9fb5b54e82994bda365a71eb864Zbigniew Jędrzejewski-Szmek r = config_parse(NULL, filename, file,
e9f3d2d508bfd9fb5b54e82994bda365a71eb864Zbigniew Jędrzejewski-Szmek "Match\0Link\0Ethernet\0",
e9f3d2d508bfd9fb5b54e82994bda365a71eb864Zbigniew Jędrzejewski-Szmek config_item_perf_lookup, link_config_gperf_lookup,
36f822c4bd077f9121757e24b6516e5c7ada63b5Zbigniew Jędrzejewski-Szmek false, false, true, link);
36f822c4bd077f9121757e24b6516e5c7ada63b5Zbigniew Jędrzejewski-Szmek if (r < 0)
ecb08ec6a5c52f2d940f3b8147e2a480affd46e1Zbigniew Jędrzejewski-Szmek return r;
36f822c4bd077f9121757e24b6516e5c7ada63b5Zbigniew Jędrzejewski-Szmek else
98a375f6d5cac24eb80d6d4e00699851324afdecTom Gundersen log_debug("Parsed configuration file %s", filename);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
dab495dc23bf9a5ba0487a057bb594355555a0e9Tom Gundersen if (link->mtu > UINT_MAX || link->speed > UINT_MAX)
dab495dc23bf9a5ba0487a057bb594355555a0e9Tom Gundersen return -ERANGE;
dab495dc23bf9a5ba0487a057bb594355555a0e9Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen link->filename = strdup(filename);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen LIST_PREPEND(links, ctx->links, link);
ecb08ec6a5c52f2d940f3b8147e2a480affd46e1Zbigniew Jędrzejewski-Szmek link = NULL;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return 0;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen}
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersenstatic bool enable_name_policy(void) {
f8a0bb5285024b6ce372c3157e761e6543ebdcd2Andreas Henriksson _cleanup_free_ char *line = NULL;
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek const char *word, *state;
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen int r;
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen size_t l;
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering r = proc_cmdline(&line);
b5884878a2874447b2a9f07f324a7cd909d96d48Lennart Poettering if (r < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to read /proc/cmdline, ignoring: %m");
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering return true;
b5884878a2874447b2a9f07f324a7cd909d96d48Lennart Poettering }
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek FOREACH_WORD_QUOTED(word, l, line, state)
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek if (strneq(word, "net.ifnames=0", l))
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen return false;
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen return true;
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen}
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersenint link_config_load(link_config_ctx *ctx) {
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen int r;
edf029b7fd9a5853a87d3ca99aac2922bb8a277eTom Gundersen _cleanup_strv_free_ char **files;
edf029b7fd9a5853a87d3ca99aac2922bb8a277eTom Gundersen char **f;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen link_configs_free(ctx);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen if (!enable_name_policy()) {
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen ctx->enable_name_policy = false;
3f85ef0f05ffc51e19f86fb83a1c51e8e3cd6817Harald Hoyer log_info("Network interface NamePolicy= disabled on kernel command line, ignoring.");
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen }
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen
97f2d76d4f4dfab8b0629c09926a05a1e5621125Tom Gundersen /* update timestamp */
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, true);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek r = conf_files_list_strv(&files, ".link", NULL, link_dirs);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "failed to enumerate link files: %m");
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen STRV_FOREACH_BACKWARDS(f, files) {
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen r = load_link(ctx, *f);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen if (r < 0)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return r;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen }
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return 0;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen}
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersenbool link_config_should_reload(link_config_ctx *ctx) {
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek return paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, false);
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen}
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
464cf22f17e0cf2d8bfa6d72b5e7a662d634f149Tom Gundersenint link_config_get(link_config_ctx *ctx, struct udev_device *device,
464cf22f17e0cf2d8bfa6d72b5e7a662d634f149Tom Gundersen link_config **ret) {
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen link_config *link;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
3b64e4d4f40baac56148c7d333d6a0053358ec7aTom Gundersen assert(ctx);
3b64e4d4f40baac56148c7d333d6a0053358ec7aTom Gundersen assert(device);
3b64e4d4f40baac56148c7d333d6a0053358ec7aTom Gundersen assert(ret);
3b64e4d4f40baac56148c7d333d6a0053358ec7aTom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen LIST_FOREACH(links, link, ctx->links) {
7eb08da4b388b920c8a894b1500c9cc7dc1f31efTom Gundersen const char* attr_value;
7eb08da4b388b920c8a894b1500c9cc7dc1f31efTom Gundersen
7eb08da4b388b920c8a894b1500c9cc7dc1f31efTom Gundersen attr_value = udev_device_get_sysattr_value(device, "address");
b3e013148603aa670bc2c060ac63d48e54d76fc2Tom Gundersen
edbb03e95a3c31bf719d5c6c46eec14d0bcb9c8fTom Gundersen if (net_match_config(link->match_mac, link->match_path, link->match_driver,
7eb08da4b388b920c8a894b1500c9cc7dc1f31efTom Gundersen link->match_type, link->match_name, link->match_host,
edbb03e95a3c31bf719d5c6c46eec14d0bcb9c8fTom Gundersen link->match_virt, link->match_kernel, link->match_arch,
eb7040ec50fbfe5aad9eaf305bd442a4a235abaaTom Gundersen attr_value ? ether_aton(attr_value) : NULL,
b3e013148603aa670bc2c060ac63d48e54d76fc2Tom Gundersen udev_device_get_property_value(device, "ID_PATH"),
9b1c2626cef16722603bded9bb52033aba34dd74Tom Gundersen udev_device_get_driver(udev_device_get_parent(device)),
bf175aafd20c9ef974709ef12c5acf836121af33Tom Gundersen udev_device_get_property_value(device, "ID_NET_DRIVER"),
b3e013148603aa670bc2c060ac63d48e54d76fc2Tom Gundersen udev_device_get_devtype(device),
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen udev_device_get_sysname(device))) {
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen if (link->match_name) {
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen unsigned char name_assign_type = NET_NAME_UNKNOWN;
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen attr_value = udev_device_get_sysattr_value(device, "name_assign_type");
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen if (attr_value)
dc75168823540076b354135f6e2de7a9a978fbcaZbigniew Jędrzejewski-Szmek (void) safe_atou8(attr_value, &name_assign_type);
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen if (name_assign_type == NET_NAME_ENUM) {
ca6038b89645c0c1bd547d6a420bf95eb3d6f4ccTom Gundersen log_warning("Config file %s applies to device based on potentially unpredictable interface name '%s'",
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen link->filename, udev_device_get_sysname(device));
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen *ret = link;
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen return 0;
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen } else if (name_assign_type == NET_NAME_RENAMED) {
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen log_warning("Config file %s matches device based on renamed interface name '%s', ignoring",
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen link->filename, udev_device_get_sysname(device));
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen
ca6038b89645c0c1bd547d6a420bf95eb3d6f4ccTom Gundersen continue;
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen }
ca6038b89645c0c1bd547d6a420bf95eb3d6f4ccTom Gundersen }
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen
ca6038b89645c0c1bd547d6a420bf95eb3d6f4ccTom Gundersen log_debug("Config file %s applies to device %s",
ca6038b89645c0c1bd547d6a420bf95eb3d6f4ccTom Gundersen link->filename, udev_device_get_sysname(device));
32bc8adcd836baff68e4d0f53b9a382f358cccf8Tom Gundersen
ca6038b89645c0c1bd547d6a420bf95eb3d6f4ccTom Gundersen *ret = link;
ca6038b89645c0c1bd547d6a420bf95eb3d6f4ccTom Gundersen
ca6038b89645c0c1bd547d6a420bf95eb3d6f4ccTom Gundersen return 0;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen }
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen }
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen *ret = NULL;
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return -ENOENT;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen}
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersenstatic bool mac_is_random(struct udev_device *device) {
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen const char *s;
f1ac700248f231b7bdac2aafe8c35650efddb89fTom Gundersen unsigned type;
f1ac700248f231b7bdac2aafe8c35650efddb89fTom Gundersen int r;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen /* if we can't get the assign type, assume it is not random */
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen s = udev_device_get_sysattr_value(device, "addr_assign_type");
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen if (!s)
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen return false;
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen
f1ac700248f231b7bdac2aafe8c35650efddb89fTom Gundersen r = safe_atou(s, &type);
f1ac700248f231b7bdac2aafe8c35650efddb89fTom Gundersen if (r < 0)
f1ac700248f231b7bdac2aafe8c35650efddb89fTom Gundersen return false;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen return type == NET_ADDR_RANDOM;
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen}
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersenstatic bool should_rename(struct udev_device *device, bool respect_predictable) {
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen const char *s;
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen unsigned type;
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen int r;
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen /* if we can't get the assgin type, assume we should rename */
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen s = udev_device_get_sysattr_value(device, "name_assign_type");
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen if (!s)
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen return true;
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen r = safe_atou(s, &type);
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen if (r < 0)
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen return true;
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen switch (type) {
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen case NET_NAME_USER:
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen case NET_NAME_RENAMED:
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen /* these were already named by userspace, do not touch again */
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen return false;
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen case NET_NAME_PREDICTABLE:
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen /* the kernel claims to have given a predictable name */
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen if (respect_predictable)
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen return false;
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen /* fall through */
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen case NET_NAME_ENUM:
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen default:
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen /* the name is known to be bad, or of an unknown type */
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen return true;
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen }
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen}
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
464cf22f17e0cf2d8bfa6d72b5e7a662d634f149Tom Gundersenstatic int get_mac(struct udev_device *device, bool want_random,
464cf22f17e0cf2d8bfa6d72b5e7a662d634f149Tom Gundersen struct ether_addr *mac) {
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering int r;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen if (want_random)
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering random_bytes(mac->ether_addr_octet, ETH_ALEN);
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen else {
dbe81cbd2a93088236a2e4e41eeb33378940f7b9Martin Pitt uint64_t result;
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering
dbe81cbd2a93088236a2e4e41eeb33378940f7b9Martin Pitt r = net_get_unique_predictable_data(device, &result);
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen if (r < 0)
55428d84f31b52da1c50b7469f14e15740547f20Tom Gundersen return r;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering assert_cc(ETH_ALEN <= sizeof(result));
dbe81cbd2a93088236a2e4e41eeb33378940f7b9Martin Pitt memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen }
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen /* see eth_random_addr in the kernel */
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen mac->ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen return 0;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen}
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
464cf22f17e0cf2d8bfa6d72b5e7a662d634f149Tom Gundersenint link_config_apply(link_config_ctx *ctx, link_config *config,
464cf22f17e0cf2d8bfa6d72b5e7a662d634f149Tom Gundersen struct udev_device *device, const char **name) {
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen const char *old_name;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen const char *new_name = NULL;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen struct ether_addr generated_mac;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen struct ether_addr *mac = NULL;
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen bool respect_predictable = false;
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen int r, ifindex;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen assert(ctx);
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen assert(config);
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen assert(device);
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen assert(name);
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen old_name = udev_device_get_sysname(device);
3e137a1b9a0eac2bf43d493d3302c3c959b6ccdbTom Gundersen if (!old_name)
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return -EINVAL;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
dab495dc23bf9a5ba0487a057bb594355555a0e9Tom Gundersen r = ethtool_set_speed(&ctx->ethtool_fd, old_name, config->speed / 1024, config->duplex);
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen if (r < 0)
dab495dc23bf9a5ba0487a057bb594355555a0e9Tom Gundersen log_warning_errno(r, "Could not set speed or duplex of %s to %zu Mbps (%s): %m",
755bde375f4db393ad06e73340bfcf4d0cf91bb2Lennart Poettering old_name, config->speed / 1024,
755bde375f4db393ad06e73340bfcf4d0cf91bb2Lennart Poettering duplex_to_string(config->duplex));
a501033335ed402c8f7e86fe41a15531ba69abd7Tom Gundersen
aedca89268ed4fd6be41e55a605f011033ad1fb5Tom Gundersen r = ethtool_set_wol(&ctx->ethtool_fd, old_name, config->wol);
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen if (r < 0)
755bde375f4db393ad06e73340bfcf4d0cf91bb2Lennart Poettering log_warning_errno(r, "Could not set WakeOnLan of %s to %s: %m",
755bde375f4db393ad06e73340bfcf4d0cf91bb2Lennart Poettering old_name, wol_to_string(config->wol));
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen ifindex = udev_device_get_ifindex(device);
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen if (ifindex <= 0) {
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen log_warning("Could not find ifindex");
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen return -ENODEV;
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen }
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen
f61942250a43a123580d7bbe5d7873dc5118ed97Tom Gundersen if (ctx->enable_name_policy && config->name_policy) {
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen NamePolicy *policy;
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen
68ba38770640413b4fa06773447666eb88a38d4cTom Gundersen for (policy = config->name_policy;
68ba38770640413b4fa06773447666eb88a38d4cTom Gundersen !new_name && *policy != _NAMEPOLICY_INVALID; policy++) {
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen switch (*policy) {
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen case NAMEPOLICY_KERNEL:
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen respect_predictable = true;
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen break;
e51660ae56bb747ece2cab8fe6eec37f4d06a438Tom Gundersen case NAMEPOLICY_DATABASE:
e51660ae56bb747ece2cab8fe6eec37f4d06a438Tom Gundersen new_name = udev_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE");
e51660ae56bb747ece2cab8fe6eec37f4d06a438Tom Gundersen break;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen case NAMEPOLICY_ONBOARD:
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen new_name = udev_device_get_property_value(device, "ID_NET_NAME_ONBOARD");
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen break;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen case NAMEPOLICY_SLOT:
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen new_name = udev_device_get_property_value(device, "ID_NET_NAME_SLOT");
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen break;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen case NAMEPOLICY_PATH:
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen new_name = udev_device_get_property_value(device, "ID_NET_NAME_PATH");
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen break;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen case NAMEPOLICY_MAC:
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen new_name = udev_device_get_property_value(device, "ID_NET_NAME_MAC");
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen break;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen default:
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen break;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen }
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen }
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen }
daeb71a36a98834664e4d95773a3629b746f4db8Tom Gundersen
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen if (should_rename(device, respect_predictable)) {
3c9b886068d99e5d3cbabcac32a4decf37244c54Tom Gundersen /* if not set by policy, fall back manually set name */
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen if (!new_name)
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen new_name = config->name;
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen } else
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen new_name = NULL;
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen switch (config->mac_policy) {
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen case MACPOLICY_PERSISTENT:
92d927f850d4b668b44f3e5f41e266d934d03726Tom Gundersen if (mac_is_random(device)) {
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen r = get_mac(device, false, &generated_mac);
1c25683e0f40c6169676cc44fa1897082597feecTom Gundersen if (r == -ENOENT) {
1c25683e0f40c6169676cc44fa1897082597feecTom Gundersen log_warning_errno(r, "Could not generate persistent MAC address for %s: %m", old_name);
a669ea9860900d5cdebbc4cb9aaea72db7e28a02Tom Gundersen break;
1c25683e0f40c6169676cc44fa1897082597feecTom Gundersen } else if (r < 0)
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen return r;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen mac = &generated_mac;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen }
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen break;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen case MACPOLICY_RANDOM:
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen if (!mac_is_random(device)) {
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen r = get_mac(device, true, &generated_mac);
1c25683e0f40c6169676cc44fa1897082597feecTom Gundersen if (r == -ENOENT) {
1c25683e0f40c6169676cc44fa1897082597feecTom Gundersen log_warning_errno(r, "Could not generate random MAC address for %s: %m", old_name);
a669ea9860900d5cdebbc4cb9aaea72db7e28a02Tom Gundersen break;
1c25683e0f40c6169676cc44fa1897082597feecTom Gundersen } else if (r < 0)
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen return r;
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen mac = &generated_mac;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen }
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen break;
66d3752e812915a549ebee01769ee761c1495667Jacob Keller case MACPOLICY_NONE:
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen default:
5fde13d748749f0e06e2e6cdd15f0980a79ea82cTom Gundersen mac = config->mac;
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen }
16b9b87aeee9353b5b8dae6089a69752422a5b09Tom Gundersen
dab495dc23bf9a5ba0487a057bb594355555a0e9Tom Gundersen r = rtnl_set_link_properties(&ctx->rtnl, ifindex, config->alias, mac, config->mtu);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_warning_errno(r, "Could not set Alias, MACAddress or MTU on %s: %m", old_name);
43b3a5ef61859f06cdbaf26765cab8e1adac4296Tom Gundersen
d95b83b87d7d7c50e550f7128827f73a321c8934Tom Gundersen *name = new_name;
d95b83b87d7d7c50e550f7128827f73a321c8934Tom Gundersen
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen return 0;
af6f0d422c521374ee6a2dd92df5935a5a476ae5Tom Gundersen}
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersenint link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret) {
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen const char *name;
a7f7d1bde43fc825c49afea3f946f5b4b3d563e0Harald Hoyer char *driver = NULL;
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen int r;
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen name = udev_device_get_sysname(device);
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen if (!name)
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen return -EINVAL;
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen
aedca89268ed4fd6be41e55a605f011033ad1fb5Tom Gundersen r = ethtool_get_driver(&ctx->ethtool_fd, name, &driver);
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen if (r < 0)
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen return r;
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen *ret = driver;
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen return 0;
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen}
847a8a5fed4d265dfa659917515c6f9bd1b8d5c4Tom Gundersen
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mackstatic const char* const mac_policy_table[_MACPOLICY_MAX] = {
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen [MACPOLICY_PERSISTENT] = "persistent",
66d3752e812915a549ebee01769ee761c1495667Jacob Keller [MACPOLICY_RANDOM] = "random",
66d3752e812915a549ebee01769ee761c1495667Jacob Keller [MACPOLICY_NONE] = "none"
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen};
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen
be32eb9b7fbcb22e4b648086d644135e38279633Tom GundersenDEFINE_STRING_TABLE_LOOKUP(mac_policy, MACPolicy);
464cf22f17e0cf2d8bfa6d72b5e7a662d634f149Tom GundersenDEFINE_CONFIG_PARSE_ENUM(config_parse_mac_policy, mac_policy, MACPolicy,
464cf22f17e0cf2d8bfa6d72b5e7a662d634f149Tom Gundersen "Failed to parse MAC address policy");
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mackstatic const char* const name_policy_table[_NAMEPOLICY_MAX] = {
04b67d49254d956d31bcfe80340fb9df7ed332d3Tom Gundersen [NAMEPOLICY_KERNEL] = "kernel",
e51660ae56bb747ece2cab8fe6eec37f4d06a438Tom Gundersen [NAMEPOLICY_DATABASE] = "database",
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen [NAMEPOLICY_ONBOARD] = "onboard",
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen [NAMEPOLICY_SLOT] = "slot",
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen [NAMEPOLICY_PATH] = "path",
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen [NAMEPOLICY_MAC] = "mac"
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen};
be32eb9b7fbcb22e4b648086d644135e38279633Tom Gundersen
be32eb9b7fbcb22e4b648086d644135e38279633Tom GundersenDEFINE_STRING_TABLE_LOOKUP(name_policy, NamePolicy);
464cf22f17e0cf2d8bfa6d72b5e7a662d634f149Tom GundersenDEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy,
464cf22f17e0cf2d8bfa6d72b5e7a662d634f149Tom Gundersen _NAMEPOLICY_INVALID,
464cf22f17e0cf2d8bfa6d72b5e7a662d634f149Tom Gundersen "Failed to parse interface name policy");