link-config.c revision 3f85ef0f05ffc51e19f86fb83a1c51e8e3cd6817
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/***
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering This file is part of systemd.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering systemd is free software; you can redistribute it and/or modify it
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering under the terms of the GNU Lesser General Public License as published by
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering (at your option) any later version.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering systemd is distributed in the hope that it will be useful, but
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Lesser General Public License for more details.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering You should have received a copy of the GNU Lesser General Public License
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering***/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <netinet/ether.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "sd-id128.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "missing.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "link-config.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "ethtool-util.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "libudev-private.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "sd-rtnl.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "util.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "log.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "strv.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "path-util.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "conf-parser.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "conf-files.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "fileio.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "hashmap.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "rtnl-util.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "network-internal.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "siphash24.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstruct link_config_ctx {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering LIST_HEAD(link_config, links);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int ethtool_fd;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering bool enable_name_policy;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering sd_rtnl *rtnl;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering usec_t link_dirs_ts_usec;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering};
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic const char* const link_dirs[] = {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "/etc/systemd/network",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "/run/systemd/network",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "/usr/lib/systemd/network",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#ifdef HAVE_SPLIT_USR
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "/lib/systemd/network",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#endif
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering NULL};
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_TRIVIAL_CLEANUP_FUNC(link_config_ctx*, link_config_ctx_free);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#define _cleanup_link_config_ctx_free_ _cleanup_(link_config_ctx_freep)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint link_config_ctx_new(link_config_ctx **ret) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering _cleanup_link_config_ctx_free_ link_config_ctx *ctx = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!ret)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -EINVAL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ctx = new0(link_config_ctx, 1);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!ctx)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -ENOMEM;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering LIST_HEAD_INIT(ctx->links);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ctx->ethtool_fd = -1;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ctx->enable_name_policy = true;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *ret = ctx;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ctx = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic void link_configs_free(link_config_ctx *ctx) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link_config *link, *link_next;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!ctx)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering LIST_FOREACH_SAFE(links, link, link_next, ctx->links) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(link->filename);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(link->match_path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(link->match_driver);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(link->match_type);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(link->description);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(link->alias);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(link->name_policy);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(link);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringvoid link_config_ctx_free(link_config_ctx *ctx) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!ctx)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering safe_close(ctx->ethtool_fd);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering sd_rtnl_unref(ctx->rtnl);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link_configs_free(ctx);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(ctx);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic int load_link(link_config_ctx *ctx, const char *filename) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering _cleanup_free_ link_config *link = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering _cleanup_fclose_ FILE *file = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(ctx);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(filename);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering file = fopen(filename, "re");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!file) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (errno == ENOENT)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -errno;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (null_or_empty_fd(fileno(file))) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("Skipping empty file: %s", filename);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link = new0(link_config, 1);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!link)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return log_oom();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link->mac_policy = _MACPOLICY_INVALID;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link->wol = _WOL_INVALID;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link->duplex = _DUP_INVALID;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = config_parse(NULL, filename, file,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "Match\0Link\0Ethernet\0",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering config_item_perf_lookup, link_config_gperf_lookup,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering false, false, true, link);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("Parsed configuration file %s", filename);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link->filename = strdup(filename);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering LIST_PREPEND(links, ctx->links, link);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic bool enable_name_policy(void) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering _cleanup_free_ char *line = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *word, *state;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering size_t l;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = proc_cmdline(&line);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to read /proc/cmdline, ignoring: %s",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r <= 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return true;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering FOREACH_WORD_QUOTED(word, l, line, state)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (strneq(word, "net.ifnames=0", l))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return true;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint link_config_load(link_config_ctx *ctx) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering _cleanup_strv_free_ char **files;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char **f;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link_configs_free(ctx);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!enable_name_policy()) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ctx->enable_name_policy = false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_info("Network interface NamePolicy= disabled on kernel command line, ignoring.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* update timestamp */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, true);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = conf_files_list_strv(&files, ".link", NULL, link_dirs);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("failed to enumerate link files: %s", strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering STRV_FOREACH_BACKWARDS(f, files) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = load_link(ctx, *f);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringbool link_config_should_reload(link_config_ctx *ctx) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, false);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint link_config_get(link_config_ctx *ctx, struct udev_device *device,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link_config **ret) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link_config *link;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering LIST_FOREACH(links, link, ctx->links) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char* attr_value = udev_device_get_sysattr_value(device, "address");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (net_match_config(link->match_mac, link->match_path, link->match_driver,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link->match_type, NULL, link->match_host,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link->match_virt, link->match_kernel, link->match_arch,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering attr_value ? ether_aton(attr_value) : NULL,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering udev_device_get_property_value(device, "ID_PATH"),
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering udev_device_get_driver(udev_device_get_parent(device)),
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering udev_device_get_property_value(device, "ID_NET_DRIVER"),
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering udev_device_get_devtype(device),
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering NULL)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("Config file %s applies to device %s",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering link->filename,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering udev_device_get_sysname(device));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *ret = link;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *ret = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -ENOENT;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic bool mac_is_random(struct udev_device *device) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *s;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned type;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* if we can't get the assign type, assume it is not random */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering s = udev_device_get_sysattr_value(device, "addr_assign_type");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!s)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = safe_atou(s, &type);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return type == NET_ADDR_RANDOM;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic bool should_rename(struct udev_device *device, bool respect_predictable) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *s;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned type;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* if we can't get the assgin type, assume we should rename */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering s = udev_device_get_sysattr_value(device, "name_assign_type");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!s)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return true;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = safe_atou(s, &type);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return true;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering switch (type) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case NET_NAME_USER:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case NET_NAME_RENAMED:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* these were already named by userspace, do not touch again */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case NET_NAME_PREDICTABLE:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* the kernel claims to have given a predictable name */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (respect_predictable)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* fall through */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case NET_NAME_ENUM:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering default:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* the name is known to be bad, or of an unknown type */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return true;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic int get_mac(struct udev_device *device, bool want_random,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct ether_addr *mac) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (want_random)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering random_bytes(mac->ether_addr_octet, ETH_ALEN);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering uint8_t result[8];
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = net_get_unique_predictable_data(device, result);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert_cc(ETH_ALEN <= sizeof(result));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering memcpy(mac->ether_addr_octet, result, ETH_ALEN);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* see eth_random_addr in the kernel */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering mac->ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint link_config_apply(link_config_ctx *ctx, link_config *config,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct udev_device *device, const char **name) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *old_name;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *new_name = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct ether_addr generated_mac;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct ether_addr *mac = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering bool respect_predictable = false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r, ifindex;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(ctx);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(config);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(device);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(name);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering old_name = udev_device_get_sysname(device);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!old_name)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -EINVAL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = ethtool_set_speed(&ctx->ethtool_fd, old_name, config->speed / 1024,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering config->duplex);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Could not set speed or duplex of %s to %u Mbps (%s): %s",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering old_name, config->speed / 1024,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering duplex_to_string(config->duplex), strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = ethtool_set_wol(&ctx->ethtool_fd, old_name, config->wol);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Could not set WakeOnLan of %s to %s: %s",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering old_name, wol_to_string(config->wol), strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ifindex = udev_device_get_ifindex(device);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (ifindex <= 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Could not find ifindex");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -ENODEV;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (ctx->enable_name_policy && config->name_policy) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering NamePolicy *policy;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering for (policy = config->name_policy;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering !new_name && *policy != _NAMEPOLICY_INVALID; policy++) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering switch (*policy) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case NAMEPOLICY_KERNEL:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering respect_predictable = true;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case NAMEPOLICY_DATABASE:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering new_name = udev_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case NAMEPOLICY_ONBOARD:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering new_name = udev_device_get_property_value(device, "ID_NET_NAME_ONBOARD");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case NAMEPOLICY_SLOT:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering new_name = udev_device_get_property_value(device, "ID_NET_NAME_SLOT");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case NAMEPOLICY_PATH:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering new_name = udev_device_get_property_value(device, "ID_NET_NAME_PATH");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case NAMEPOLICY_MAC:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering new_name = udev_device_get_property_value(device, "ID_NET_NAME_MAC");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering default:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (should_rename(device, respect_predictable)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* if not set by policy, fall back manually set name */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!new_name)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering new_name = config->name;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering } else
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering new_name = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering switch (config->mac_policy) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case MACPOLICY_PERSISTENT:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (mac_is_random(device)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = get_mac(device, false, &generated_mac);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r == -ENOENT)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering mac = &generated_mac;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case MACPOLICY_RANDOM:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!mac_is_random(device)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = get_mac(device, true, &generated_mac);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r == -ENOENT)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering mac = &generated_mac;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering default:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering mac = config->mac;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = rtnl_set_link_properties(&ctx->rtnl, ifindex, config->alias, mac,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering config->mtu);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Could not set Alias, MACAddress or MTU on %s: %s",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering old_name, strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *name = new_name;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringint link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *name;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *driver;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering name = udev_device_get_sysname(device);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!name)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -EINVAL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = ethtool_get_driver(&ctx->ethtool_fd, name, &driver);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *ret = driver;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic const char* const mac_policy_table[_MACPOLICY_MAX] = {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [MACPOLICY_PERSISTENT] = "persistent",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [MACPOLICY_RANDOM] = "random"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering};
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_STRING_TABLE_LOOKUP(mac_policy, MACPolicy);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_CONFIG_PARSE_ENUM(config_parse_mac_policy, mac_policy, MACPolicy,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "Failed to parse MAC address policy");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic const char* const name_policy_table[_NAMEPOLICY_MAX] = {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [NAMEPOLICY_KERNEL] = "kernel",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [NAMEPOLICY_DATABASE] = "database",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [NAMEPOLICY_ONBOARD] = "onboard",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [NAMEPOLICY_SLOT] = "slot",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [NAMEPOLICY_PATH] = "path",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [NAMEPOLICY_MAC] = "mac"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering};
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_STRING_TABLE_LOOKUP(name_policy, NamePolicy);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering _NAMEPOLICY_INVALID,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "Failed to parse interface name policy");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering