diff options
-rw-r--r-- | man/systemd.link.xml | 14 | ||||
-rw-r--r-- | network/99-default.link | 2 | ||||
-rw-r--r-- | src/shared/missing.h | 20 | ||||
-rw-r--r-- | src/udev/net/link-config.c | 54 | ||||
-rw-r--r-- | src/udev/net/link-config.h | 1 |
5 files changed, 78 insertions, 13 deletions
diff --git a/man/systemd.link.xml b/man/systemd.link.xml index 05effc3b71..6075b39b79 100644 --- a/man/systemd.link.xml +++ b/man/systemd.link.xml @@ -236,11 +236,21 @@ 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:</para> + <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 diff --git a/network/99-default.link b/network/99-default.link index 53215f633b..79538f9b29 100644 --- a/network/99-default.link +++ b/network/99-default.link @@ -1,3 +1,3 @@ [Link] -NamePolicy=database onboard slot path +NamePolicy=kernel database onboard slot path MACAddressPolicy=persistent diff --git a/src/shared/missing.h b/src/shared/missing.h index e20f9bdfd3..195edfc672 100644 --- a/src/shared/missing.h +++ b/src/shared/missing.h @@ -525,3 +525,23 @@ static inline int setns(int fd, int nstype) { #ifndef BOND_XMIT_POLICY_ENCAP34 #define BOND_XMIT_POLICY_ENCAP34 4 #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 diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 946715ce5a..b44aeaf6db 100644 --- a/src/udev/net/link-config.c +++ b/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" @@ -283,8 +284,33 @@ static bool mac_is_random(struct udev_device *device) { if (r < 0) return false; - /* check for NET_ADDR_RANDOM */ - return type == 1; + return type == NET_ADDR_RANDOM; +} + +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) { @@ -315,6 +341,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev const char *new_name = NULL; struct ether_addr generated_mac; struct ether_addr *mac = NULL; + bool respect_predictable = false; int r, ifindex; 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) { 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; @@ -373,12 +404,14 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev } } - 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; + + *name = new_name; switch (config->mac_policy) { 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"); static const char* const name_policy_table[_NAMEPOLICY_MAX] = { + [NAMEPOLICY_KERNEL] = "kernel", [NAMEPOLICY_DATABASE] = "database", [NAMEPOLICY_ONBOARD] = "onboard", [NAMEPOLICY_SLOT] = "slot", diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h index 24fdb87e4c..5f3d4ad142 100644 --- a/src/udev/net/link-config.h +++ b/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, |