link-config.c revision 9a4b012e43f23516373bf398dd9a458439d19939
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers This file is part of systemd.
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers systemd is free software; you can redistribute it and/or modify it
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers under the terms of the GNU Lesser General Public License as published by
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers the Free Software Foundation; either version 2.1 of the License, or
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers (at your option) any later version.
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers systemd is distributed in the hope that it will be useful, but
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers WITHOUT ANY WARRANTY; without even the implied warranty of
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers Lesser General Public License for more details.
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers You should have received a copy of the GNU Lesser General Public License
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers along with systemd; If not, see <http://www.gnu.org/licenses/>.
2f8d336478536af789d654599f9523d02e0ca693Kay Sieversstatic const char* const link_dirs[] = {
2f8d336478536af789d654599f9523d02e0ca693Kay Sieversstatic void link_config_free(link_config *link) {
2f8d336478536af789d654599f9523d02e0ca693Kay SieversDEFINE_TRIVIAL_CLEANUP_FUNC(link_config*, link_config_free);
2f8d336478536af789d654599f9523d02e0ca693Kay Sieversstatic void link_configs_free(link_config_ctx *ctx) {
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers LIST_FOREACH_SAFE(links, link, link_next, ctx->links)
2f8d336478536af789d654599f9523d02e0ca693Kay Sieversvoid link_config_ctx_free(link_config_ctx *ctx) {
2f8d336478536af789d654599f9523d02e0ca693Kay SieversDEFINE_TRIVIAL_CLEANUP_FUNC(link_config_ctx*, link_config_ctx_free);
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers _cleanup_(link_config_ctx_freep) link_config_ctx *ctx = NULL;
2f8d336478536af789d654599f9523d02e0ca693Kay Sieversstatic int load_link(link_config_ctx *ctx, const char *filename) {
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers _cleanup_(link_config_freep) link_config *link = NULL;
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers "Match\0Link\0Ethernet\0",
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers config_item_perf_lookup, link_config_gperf_lookup,
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers false, false, true, link);
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers log_debug("Parsed configuration file %s", filename);
2f8d336478536af789d654599f9523d02e0ca693Kay Sieversstatic bool enable_name_policy(void) {
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers if (r < 0) {
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers log_warning_errno(r, "Failed to read /proc/cmdline, ignoring: %m");
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers return true;
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers return false;
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers return true;
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers log_info("Network interface NamePolicy= disabled on kernel command line, ignoring.");
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers /* update timestamp */
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, true);
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers r = conf_files_list_strv(&files, ".link", NULL, link_dirs);
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers return log_error_errno(r, "failed to enumerate link files: %m");
2f8d336478536af789d654599f9523d02e0ca693Kay Sieversbool link_config_should_reload(link_config_ctx *ctx) {
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers return paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, false);
2f8d336478536af789d654599f9523d02e0ca693Kay Sieversint link_config_get(link_config_ctx *ctx, struct udev_device *device,
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers attr_value = udev_device_get_sysattr_value(device, "address");
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers if (net_match_config(link->match_mac, link->match_path, link->match_driver,
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers link->match_type, link->match_name, link->match_host,
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers link->match_virt, link->match_kernel, link->match_arch,
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers udev_device_get_property_value(device, "ID_PATH"),
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers udev_device_get_driver(udev_device_get_parent(device)),
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers udev_device_get_property_value(device, "ID_NET_DRIVER"),
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers unsigned char name_assign_type = NET_NAME_UNKNOWN;
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers attr_value = udev_device_get_sysattr_value(device, "name_assign_type");
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers (void)safe_atou8(attr_value, &name_assign_type);
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers log_warning("Config file %s applies to device based on potentially unpredictable interface name '%s'",
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers link->filename, udev_device_get_sysname(device));
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers } else if (name_assign_type == NET_NAME_RENAMED) {
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers log_warning("Config file %s matches device based on renamed interface name '%s', ignoring",
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers link->filename, udev_device_get_sysname(device));
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers log_debug("Config file %s applies to device %s",
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers link->filename, udev_device_get_sysname(device));
2f8d336478536af789d654599f9523d02e0ca693Kay Sieversstatic bool mac_is_random(struct udev_device *device) {
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers const char *s;
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers /* if we can't get the assign type, assume it is not random */
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers s = udev_device_get_sysattr_value(device, "addr_assign_type");
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers return false;
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers return false;
2f8d336478536af789d654599f9523d02e0ca693Kay Sieversstatic bool should_rename(struct udev_device *device, bool respect_predictable) {
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers const char *s;
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers /* if we can't get the assgin type, assume we should rename */
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers s = udev_device_get_sysattr_value(device, "name_assign_type");
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers return true;
2f8d336478536af789d654599f9523d02e0ca693Kay Sievers return true;
switch (type) {
case NET_NAME_USER:
case NET_NAME_RENAMED:
case NET_NAME_PREDICTABLE:
if (respect_predictable)
case NET_NAME_ENUM:
if (want_random)
const char *old_name;
bool respect_predictable = false;
int r, ifindex;
if (!old_name)
return -EINVAL;
if (ifindex <= 0) {
return -ENODEV;
switch (*policy) {
case NAMEPOLICY_KERNEL:
respect_predictable = true;
case NAMEPOLICY_DATABASE:
case NAMEPOLICY_ONBOARD:
case NAMEPOLICY_SLOT:
case NAMEPOLICY_PATH:
case NAMEPOLICY_MAC:
if (!new_name)
case MACPOLICY_PERSISTENT:
if (r == -ENOENT)
case MACPOLICY_RANDOM:
if (r == -ENOENT)
const char *name;
char *driver;
if (!name)
return -EINVAL;