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.
This commit is contained in:
Tom Gundersen 2014-07-15 17:57:43 +02:00
parent f3fc48150b
commit 04b67d4925
5 changed files with 78 additions and 13 deletions

View file

@ -236,10 +236,20 @@
not set directly, but is exported to udev as not set directly, but is exported to udev as
the property <literal>ID_NET_NAME</literal>, the property <literal>ID_NET_NAME</literal>,
which is, by default, used by a udev rule to set which is, by default, used by a udev rule to set
<literal>NAME</literal>. The available policies <literal>NAME</literal>. If the name has already
are:</para> been set by userspace, no renaming is performed.
The available policies are:</para>
<variablelist> <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> <varlistentry>
<term><literal>database</literal></term> <term><literal>database</literal></term>
<listitem> <listitem>

View file

@ -1,3 +1,3 @@
[Link] [Link]
NamePolicy=database onboard slot path NamePolicy=kernel database onboard slot path
MACAddressPolicy=persistent MACAddressPolicy=persistent

View file

@ -525,3 +525,23 @@ static inline int setns(int fd, int nstype) {
#ifndef BOND_XMIT_POLICY_ENCAP34 #ifndef BOND_XMIT_POLICY_ENCAP34
#define BOND_XMIT_POLICY_ENCAP34 4 #define BOND_XMIT_POLICY_ENCAP34 4
#endif #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

View file

@ -20,10 +20,11 @@
***/ ***/
#include <netinet/ether.h> #include <netinet/ether.h>
#include <net/if.h> #include <linux/netdevice.h>
#include "sd-id128.h" #include "sd-id128.h"
#include "missing.h"
#include "link-config.h" #include "link-config.h"
#include "ethtool-util.h" #include "ethtool-util.h"
@ -283,8 +284,33 @@ static bool mac_is_random(struct udev_device *device) {
if (r < 0) if (r < 0)
return false; return false;
/* check for NET_ADDR_RANDOM */ return type == NET_ADDR_RANDOM;
return type == 1; }
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, "name_assign_type");
if (!s)
return true; /* if we don't know, assume we should rename */
r = safe_atou(s, &type);
if (r < 0)
return true;
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 */
}
} }
static int get_mac(struct udev_device *device, bool want_random, struct ether_addr *mac) { static int get_mac(struct udev_device *device, bool want_random, struct ether_addr *mac) {
@ -315,6 +341,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev
const char *new_name = NULL; const char *new_name = NULL;
struct ether_addr generated_mac; struct ether_addr generated_mac;
struct ether_addr *mac = NULL; struct ether_addr *mac = NULL;
bool respect_predictable = false;
int r, ifindex; int r, ifindex;
assert(ctx); assert(ctx);
@ -350,8 +377,12 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev
if (ctx->enable_name_policy && config->name_policy) { if (ctx->enable_name_policy && config->name_policy) {
NamePolicy *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) { switch (*policy) {
case NAMEPOLICY_KERNEL:
respect_predictable = true;
break;
case NAMEPOLICY_DATABASE: case NAMEPOLICY_DATABASE:
new_name = udev_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE"); new_name = udev_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE");
break; break;
@ -373,12 +404,14 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev
} }
} }
if (new_name) if (should_rename(device, respect_predictable)) {
*name = new_name; /* a name was set by a policy */ if (!new_name)
else if (config->name) /* if not set by policy, fall back manually set name */
*name = config->name; /* a name was set manually in the config */ new_name = config->name;
else } else
*name = NULL; new_name = NULL;
*name = new_name;
switch (config->mac_policy) { switch (config->mac_policy) {
case MACPOLICY_PERSISTENT: case MACPOLICY_PERSISTENT:
@ -444,6 +477,7 @@ DEFINE_STRING_TABLE_LOOKUP(mac_policy, MACPolicy);
DEFINE_CONFIG_PARSE_ENUM(config_parse_mac_policy, mac_policy, MACPolicy, "Failed to parse MAC address policy"); DEFINE_CONFIG_PARSE_ENUM(config_parse_mac_policy, mac_policy, MACPolicy, "Failed to parse MAC address policy");
static const char* const name_policy_table[_NAMEPOLICY_MAX] = { static const char* const name_policy_table[_NAMEPOLICY_MAX] = {
[NAMEPOLICY_KERNEL] = "kernel",
[NAMEPOLICY_DATABASE] = "database", [NAMEPOLICY_DATABASE] = "database",
[NAMEPOLICY_ONBOARD] = "onboard", [NAMEPOLICY_ONBOARD] = "onboard",
[NAMEPOLICY_SLOT] = "slot", [NAMEPOLICY_SLOT] = "slot",

View file

@ -39,6 +39,7 @@ typedef enum MACPolicy {
} MACPolicy; } MACPolicy;
typedef enum NamePolicy { typedef enum NamePolicy {
NAMEPOLICY_KERNEL,
NAMEPOLICY_DATABASE, NAMEPOLICY_DATABASE,
NAMEPOLICY_ONBOARD, NAMEPOLICY_ONBOARD,
NAMEPOLICY_SLOT, NAMEPOLICY_SLOT,