systemd/1098-udev-link_setup-respect-kernel-name-assign-policy.patch

207 lines
7.3 KiB
Diff

Based on 04b67d49254d956d31bcfe80340fb9df7ed332d3 Mon Sep 17 00:00:00 2001
From: Tom Gundersen <teg@jklm.no>
Date: Tue, 15 Jul 2014 17:57:43 +0200
Subject: [PATCH] udev: link_setup - respect kernel name assign policy
Newer kernels export meta-information about the origin of an ifname. Respect this
from the ifname rename logic. We do not rename any interfaces that was originally
named by userspace, nor once which have already been renamed from userspace.
Moreover, we optionally do not (the default) rename interfaces which the kernel
claims to have named in a predictable way.
---
man/udev.xml | 13 ++++++++++-
network/99-default.link | 2 -
src/shared/missing.h | 21 +++++++++++++++++
src/udev/net/link-config.c | 53 +++++++++++++++++++++++++++++++++++++--------
src/udev/net/link-config.h | 1
5 files changed, 79 insertions(+), 11 deletions(-)
--- man/udev.xml
+++ man/udev.xml
@@ -914,10 +914,21 @@
successful one is used. The name is not set directly, but
is exported to udev as the property <literal>ID_NET_NAME</literal>,
which is, by default, used by a udev rule to set
- <literal>NAME</literal>. The available policies are:
+ <literal>NAME</literal>. If the name has already
+ been set by userspace, no renaming is performed.
+ The available policies are:
</para>
<variablelist>
<varlistentry>
+ <term><literal>kernel</literal></term>
+ <listitem>
+ <para>If the kernel claims that the name it
+ has set for a device is predictable, then
+ no renaming is performed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><literal>database</literal></term>
<listitem>
<para>The name is set based on entries in the Hardware
--- network/99-default.link
+++ network/99-default.link
@@ -1,3 +1,3 @@
[Link]
-NamePolicy=database onboard slot path
+NamePolicy=kernel database onboard slot path
MACAddressPolicy=persistent
--- src/shared/missing.h
+++ src/shared/missing.h
@@ -362,3 +362,24 @@ static inline int setns(int fd, int nsty
return syscall(__NR_setns, fd, nstype);
}
#endif
+
+#ifndef NET_ADDR_RANDOM
+# define NET_ADDR_RANDOM 1
+#endif
+
+#ifndef NET_NAME_ENUM
+# define NET_NAME_ENUM 1
+#endif
+
+#ifndef NET_NAME_PREDICTABLE
+# define NET_NAME_PREDICTABLE 2
+#endif
+
+#ifndef NET_NAME_USER
+# define NET_NAME_USER 3
+#endif
+
+#ifndef NET_NAME_RENAMED
+# define NET_NAME_RENAMED 4
+#endif
+
--- src/udev/net/link-config.c
+++ src/udev/net/link-config.c
@@ -20,10 +20,11 @@
***/
#include <netinet/ether.h>
-#include <net/if.h>
+#include <linux/netdevice.h>
#include "sd-id128.h"
+#include "missing.h"
#include "link-config.h"
#include "ethtool-util.h"
@@ -297,23 +298,33 @@ static bool mac_is_random(struct udev_de
return false;
/* check for NET_ADDR_RANDOM */
- return type == 1;
+ return type == NET_ADDR_RANDOM;
}
-static bool mac_is_permanent(struct udev_device *device) {
+static bool should_rename(struct udev_device *device, bool respect_predictable) {
const char *s;
unsigned type;
int r;
- s = udev_device_get_sysattr_value(device, "addr_assign_type");
+ s = udev_device_get_sysattr_value(device, "name_assign_type");
if (!s)
- return true; /* if we don't know, assume it is permanent */
+ return true; /* if we don't know, assume we should rename */
r = safe_atou(s, &type);
if (r < 0)
return true;
- /* check for NET_ADDR_PERM */
- return type == 0;
+ switch (type) {
+ case NET_NAME_USER:
+ case NET_NAME_RENAMED:
+ return false; /* these were already named by userspace, do not touch again */
+ case NET_NAME_PREDICTABLE:
+ if (respect_predictable)
+ return false; /* the kernel claims to have given a predictable name */
+ /* fall through */
+ case NET_NAME_ENUM:
+ default:
+ return true; /* the name is known to be bad, or of an unknown type */
+ }
}
#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
@@ -371,6 +382,7 @@ int link_config_apply(link_config_ctx *c
const char *new_name = NULL;
struct ether_addr generated_mac;
struct ether_addr *mac = NULL;
+ bool respect_predictable = false;
int r, ifindex;
assert(ctx);
@@ -406,8 +418,12 @@ int link_config_apply(link_config_ctx *c
if (ctx->enable_name_policy && config->name_policy) {
NamePolicy *policy;
- for (policy = config->name_policy; !new_name && *policy != _NAMEPOLICY_INVALID; policy++) {
+ for (policy = config->name_policy; !respect_predictable && !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;
@@ -429,16 +445,16 @@ int link_config_apply(link_config_ctx *c
}
}
- if (new_name)
- *name = new_name; /* a name was set by a policy */
- else if (config->name)
- *name = config->name; /* a name was set manually in the config */
- else
- *name = NULL;
+ if (should_rename(device, respect_predictable)) {
+ if (!new_name)
+ /* if not set by policy, fall back manually set name */
+ new_name = config->name;
+ } else
+ new_name = NULL;
switch (config->mac_policy) {
case MACPOLICY_PERSISTENT:
- if (!mac_is_permanent(device)) {
+ if (mac_is_random(device)) {
r = get_mac(device, false, &generated_mac);
if (r == -ENOENT)
break;
@@ -467,6 +483,8 @@ int link_config_apply(link_config_ctx *c
return r;
}
+ *name = new_name;
+
return 0;
}
@@ -500,6 +518,7 @@ DEFINE_STRING_TABLE_LOOKUP(mac_policy, M
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_KERNEL] = "kernel",
[NAMEPOLICY_DATABASE] = "database",
[NAMEPOLICY_ONBOARD] = "onboard",
[NAMEPOLICY_SLOT] = "slot",
--- src/udev/net/link-config.h
+++ src/udev/net/link-config.h
@@ -39,6 +39,7 @@ typedef enum MACPolicy {
} MACPolicy;
typedef enum NamePolicy {
+ NAMEPOLICY_KERNEL,
NAMEPOLICY_DATABASE,
NAMEPOLICY_ONBOARD,
NAMEPOLICY_SLOT,