You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
8.7 KiB
170 lines
8.7 KiB
From 2faf160d0b8122e0dca603a441db68dc38c1bab6 Mon Sep 17 00:00:00 2001
|
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
Date: Mon, 16 Dec 2019 23:44:42 +0900
|
|
Subject: [PATCH] udev: introduce AlternativeNamesPolicy= setting
|
|
|
|
(cherry picked from commit ef1d2c07f9567dfea8a4e012d8779a4ded2d9ae6)
|
|
|
|
Related: #2005008
|
|
---
|
|
man/systemd.link.xml | 11 +++++
|
|
src/udev/net/link-config-gperf.gperf | 1 +
|
|
src/udev/net/link-config.c | 62 ++++++++++++++++++++++++++--
|
|
src/udev/net/link-config.h | 5 +++
|
|
4 files changed, 76 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/man/systemd.link.xml b/man/systemd.link.xml
|
|
index c8ebb751ee..13dcce0879 100644
|
|
--- a/man/systemd.link.xml
|
|
+++ b/man/systemd.link.xml
|
|
@@ -343,6 +343,17 @@
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
+ <varlistentry>
|
|
+ <term><varname>AlternativeNamesPolicy=</varname></term>
|
|
+ <listitem>
|
|
+ <para>A space-separated list of policies by which the interface's alternative names
|
|
+ should be set. Each of the policies may fail, and all successful policies are used. The
|
|
+ available policies are <literal>database</literal>, <literal>onboard</literal>,
|
|
+ <literal>slot</literal>, <literal>path</literal>, and <literal>mac</literal>. If the
|
|
+ kernel does not support the alternative names, then this setting will be ignored.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
<varlistentry>
|
|
<term><varname>AlternativeName=</varname></term>
|
|
<listitem>
|
|
diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
|
|
index 913c754145..df8404e7b8 100644
|
|
--- a/src/udev/net/link-config-gperf.gperf
|
|
+++ b/src/udev/net/link-config-gperf.gperf
|
|
@@ -35,6 +35,7 @@ Link.MACAddress, config_parse_hwaddr, 0,
|
|
Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy)
|
|
Link.Name, config_parse_ifname, 0, offsetof(link_config, name)
|
|
Link.AlternativeName, config_parse_ifnames, 1, offsetof(link_config, alternative_names)
|
|
+Link.AlternativeNamesPolicy, config_parse_alternative_names_policy, 0, offsetof(link_config, alternative_names_policy)
|
|
Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias)
|
|
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu)
|
|
Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed)
|
|
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
|
|
index 8e88c8e5c4..6ceb4c698e 100644
|
|
--- a/src/udev/net/link-config.c
|
|
+++ b/src/udev/net/link-config.c
|
|
@@ -69,6 +69,7 @@ static void link_config_free(link_config *link) {
|
|
free(link->name_policy);
|
|
free(link->name);
|
|
strv_free(link->alternative_names);
|
|
+ free(link->alternative_names_policy);
|
|
free(link->alias);
|
|
|
|
free(link);
|
|
@@ -349,6 +350,7 @@ static int get_mac(struct udev_device *device, bool want_random,
|
|
|
|
int link_config_apply(link_config_ctx *ctx, link_config *config,
|
|
struct udev_device *device, const char **name) {
|
|
+ _cleanup_strv_free_ char **altnames = NULL;
|
|
bool respect_predictable = false;
|
|
struct ether_addr generated_mac;
|
|
struct ether_addr *mac = NULL;
|
|
@@ -473,11 +475,52 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
|
|
if (r < 0)
|
|
return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name);
|
|
|
|
- r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, config->alternative_names);
|
|
+ if (config->alternative_names) {
|
|
+ altnames = strv_copy(config->alternative_names);
|
|
+ if (!altnames)
|
|
+ return log_oom();
|
|
+ }
|
|
+
|
|
+ if (config->alternative_names_policy)
|
|
+ for (NamePolicy *p = config->alternative_names_policy; *p != _NAMEPOLICY_INVALID; p++) {
|
|
+ const char *n;
|
|
+
|
|
+ switch (*p) {
|
|
+ case NAMEPOLICY_DATABASE:
|
|
+ n = udev_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE");
|
|
+ break;
|
|
+ case NAMEPOLICY_ONBOARD:
|
|
+ n = udev_device_get_property_value(device, "ID_NET_NAME_ONBOARD");
|
|
+ break;
|
|
+ case NAMEPOLICY_SLOT:
|
|
+ n = udev_device_get_property_value(device, "ID_NET_NAME_SLOT");
|
|
+ break;
|
|
+ case NAMEPOLICY_PATH:
|
|
+ n = udev_device_get_property_value(device, "ID_NET_NAME_PATH");
|
|
+ break;
|
|
+ case NAMEPOLICY_MAC:
|
|
+ n = udev_device_get_property_value(device, "ID_NET_NAME_MAC");
|
|
+ break;
|
|
+ default:
|
|
+ assert_not_reached("invalid policy");
|
|
+ }
|
|
+ if (!isempty(n)) {
|
|
+ r = strv_extend(&altnames, n);
|
|
+ if (r < 0)
|
|
+ return log_oom();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (new_name)
|
|
+ strv_remove(altnames, new_name);
|
|
+ strv_remove(altnames, old_name);
|
|
+ strv_uniq(altnames);
|
|
+
|
|
+ r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, altnames);
|
|
if (r == -EOPNOTSUPP)
|
|
- log_debug_errno(r, "Could not set AlternativeName= on %s, ignoring: %m", old_name);
|
|
+ log_debug_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s, ignoring: %m", old_name);
|
|
else if (r < 0)
|
|
- return log_warning_errno(r, "Could not set AlternativeName= on %s: %m", old_name);
|
|
+ return log_warning_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s: %m", old_name);
|
|
|
|
*name = new_name;
|
|
|
|
@@ -524,3 +567,16 @@ DEFINE_STRING_TABLE_LOOKUP(name_policy, NamePolicy);
|
|
DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy,
|
|
_NAMEPOLICY_INVALID,
|
|
"Failed to parse interface name policy");
|
|
+
|
|
+static const char* const alternative_names_policy_table[_NAMEPOLICY_MAX] = {
|
|
+ [NAMEPOLICY_DATABASE] = "database",
|
|
+ [NAMEPOLICY_ONBOARD] = "onboard",
|
|
+ [NAMEPOLICY_SLOT] = "slot",
|
|
+ [NAMEPOLICY_PATH] = "path",
|
|
+ [NAMEPOLICY_MAC] = "mac",
|
|
+};
|
|
+
|
|
+DEFINE_STRING_TABLE_LOOKUP(alternative_names_policy, NamePolicy);
|
|
+DEFINE_CONFIG_PARSE_ENUMV(config_parse_alternative_names_policy, alternative_names_policy, NamePolicy,
|
|
+ _NAMEPOLICY_INVALID,
|
|
+ "Failed to parse alternative names policy");
|
|
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
|
|
index 93d5fdce59..634bd2ec54 100644
|
|
--- a/src/udev/net/link-config.h
|
|
+++ b/src/udev/net/link-config.h
|
|
@@ -49,6 +49,7 @@ struct link_config {
|
|
struct ether_addr *mac;
|
|
MACPolicy mac_policy;
|
|
NamePolicy *name_policy;
|
|
+ NamePolicy *alternative_names_policy;
|
|
char *name;
|
|
char **alternative_names;
|
|
char *alias;
|
|
@@ -78,6 +79,9 @@ int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret
|
|
const char *name_policy_to_string(NamePolicy p) _const_;
|
|
NamePolicy name_policy_from_string(const char *p) _pure_;
|
|
|
|
+const char *alternative_names_policy_to_string(NamePolicy p) _const_;
|
|
+NamePolicy alternative_names_policy_from_string(const char *p) _pure_;
|
|
+
|
|
const char *mac_policy_to_string(MACPolicy p) _const_;
|
|
MACPolicy mac_policy_from_string(const char *p) _pure_;
|
|
|
|
@@ -86,3 +90,4 @@ const struct ConfigPerfItem* link_config_gperf_lookup(const char *key, GPERF_LEN
|
|
|
|
int config_parse_mac_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
|
int config_parse_name_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
|
+int config_parse_alternative_names_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|