234 lines
8.3 KiB
Diff
234 lines
8.3 KiB
Diff
From 11f76dbf187708c3eda4a4daeb058f544ea28af5 Mon Sep 17 00:00:00 2001
|
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
Date: Tue, 16 May 2023 12:28:23 +0900
|
|
Subject: [PATCH] udev/net: assign alternative names only on add uevent
|
|
|
|
Previously, we first assign alternative names to a network interface,
|
|
then later change its main name if requested. So, we could not assign
|
|
the name that currently assigned as the main name of an interface as an
|
|
alternative name. So, we retry to assign the previous main name as an
|
|
alternative name on later move uevent.
|
|
|
|
However, that causes some confusing situation. E.g. if a .link file has
|
|
```
|
|
Name=foo
|
|
AlternativeNames=foo baz
|
|
```
|
|
then even if the interface is renamed by a user e.g. by invoking 'ip link'
|
|
command manually, the interface can be still referenced as 'foo', as the
|
|
name is now assigned as an alternative name.
|
|
|
|
This makes the order of name assignment inverse: the main name is first
|
|
changed, and then the requested alternative names are assigned. And
|
|
udevd do not assign alternative names on move uevent.
|
|
|
|
Replaces #27506.
|
|
|
|
(cherry picked from commit 9094ae52caca0c19ff6abdbd95d17d8e401ea3b1)
|
|
|
|
Resolves: RHEL-5988
|
|
---
|
|
src/udev/net/link-config.c | 37 ++++++++-------------
|
|
src/udev/net/link-config.h | 1 +
|
|
src/udev/udev-builtin-net_setup_link.c | 2 ++
|
|
src/udev/udev-event.c | 45 ++++++++++++++++++++++----
|
|
src/udev/udev-event.h | 1 +
|
|
5 files changed, 55 insertions(+), 31 deletions(-)
|
|
|
|
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
|
|
index c9789bcb7c..2d8c902fd3 100644
|
|
--- a/src/udev/net/link-config.c
|
|
+++ b/src/udev/net/link-config.c
|
|
@@ -363,6 +363,7 @@ Link *link_free(Link *link) {
|
|
sd_device_unref(link->device);
|
|
free(link->kind);
|
|
free(link->driver);
|
|
+ strv_free(link->altnames);
|
|
return mfree(link);
|
|
}
|
|
|
|
@@ -791,19 +792,22 @@ no_rename:
|
|
return 0;
|
|
}
|
|
|
|
-static int link_apply_alternative_names(Link *link, sd_netlink **rtnl) {
|
|
- _cleanup_strv_free_ char **altnames = NULL, **current_altnames = NULL;
|
|
+static int link_generate_alternative_names(Link *link) {
|
|
+ _cleanup_strv_free_ char **altnames = NULL;
|
|
LinkConfig *config;
|
|
sd_device *device;
|
|
int r;
|
|
|
|
assert(link);
|
|
- assert(link->config);
|
|
- assert(link->device);
|
|
- assert(rtnl);
|
|
+ config = ASSERT_PTR(link->config);
|
|
+ device = ASSERT_PTR(link->device);
|
|
+ assert(!link->altnames);
|
|
|
|
- config = link->config;
|
|
- device = link->device;
|
|
+ if (link->action != SD_DEVICE_ADD) {
|
|
+ log_link_debug(link, "Skipping to apply AlternativeNames= and AlternativeNamesPolicy= on '%s' uevent.",
|
|
+ device_action_to_string(link->action));
|
|
+ return 0;
|
|
+ }
|
|
|
|
if (config->alternative_names) {
|
|
altnames = strv_copy(config->alternative_names);
|
|
@@ -841,22 +845,7 @@ static int link_apply_alternative_names(Link *link, sd_netlink **rtnl) {
|
|
}
|
|
}
|
|
|
|
- strv_remove(altnames, link->ifname);
|
|
-
|
|
- r = rtnl_get_link_alternative_names(rtnl, link->ifindex, ¤t_altnames);
|
|
- if (r < 0)
|
|
- log_link_debug_errno(link, r, "Failed to get alternative names, ignoring: %m");
|
|
-
|
|
- STRV_FOREACH(p, current_altnames)
|
|
- strv_remove(altnames, *p);
|
|
-
|
|
- strv_uniq(altnames);
|
|
- strv_sort(altnames);
|
|
- r = rtnl_set_link_alternative_names(rtnl, link->ifindex, altnames);
|
|
- if (r < 0)
|
|
- log_link_full_errno(link, r == -EOPNOTSUPP ? LOG_DEBUG : LOG_WARNING, r,
|
|
- "Could not set AlternativeName= or apply AlternativeNamesPolicy=, ignoring: %m");
|
|
-
|
|
+ link->altnames = TAKE_PTR(altnames);
|
|
return 0;
|
|
}
|
|
|
|
@@ -958,7 +947,7 @@ int link_apply_config(LinkConfigContext *ctx, sd_netlink **rtnl, Link *link) {
|
|
if (r < 0)
|
|
return r;
|
|
|
|
- r = link_apply_alternative_names(link, rtnl);
|
|
+ r = link_generate_alternative_names(link);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
|
|
index ea9f560f45..874a391543 100644
|
|
--- a/src/udev/net/link-config.h
|
|
+++ b/src/udev/net/link-config.h
|
|
@@ -27,6 +27,7 @@ typedef struct Link {
|
|
int ifindex;
|
|
const char *ifname;
|
|
const char *new_name;
|
|
+ char **altnames;
|
|
|
|
LinkConfig *config;
|
|
sd_device *device;
|
|
diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c
|
|
index 4bf42cd492..e964bf7bf4 100644
|
|
--- a/src/udev/udev-builtin-net_setup_link.c
|
|
+++ b/src/udev/udev-builtin-net_setup_link.c
|
|
@@ -49,6 +49,8 @@ static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv, bool
|
|
if (link->new_name)
|
|
udev_builtin_add_property(dev, test, "ID_NET_NAME", link->new_name);
|
|
|
|
+ event->altnames = TAKE_PTR(link->altnames);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
|
|
index 2662806d61..3315d34eff 100644
|
|
--- a/src/udev/udev-event.c
|
|
+++ b/src/udev/udev-event.c
|
|
@@ -88,6 +88,7 @@ UdevEvent *udev_event_free(UdevEvent *event) {
|
|
ordered_hashmap_free_free_free(event->seclabel_list);
|
|
free(event->program_result);
|
|
free(event->name);
|
|
+ strv_free(event->altnames);
|
|
|
|
return mfree(event);
|
|
}
|
|
@@ -918,9 +919,6 @@ static int rename_netif(UdevEvent *event) {
|
|
|
|
dev = ASSERT_PTR(event->dev);
|
|
|
|
- if (!device_for_action(dev, SD_DEVICE_ADD))
|
|
- return 0; /* Rename the interface only when it is added. */
|
|
-
|
|
r = sd_device_get_ifindex(dev, &ifindex);
|
|
if (r == -ENOENT)
|
|
return 0; /* Device is not a network interface. */
|
|
@@ -980,7 +978,7 @@ static int rename_netif(UdevEvent *event) {
|
|
goto revert;
|
|
}
|
|
|
|
- r = rtnl_set_link_name(&event->rtnl, ifindex, event->name, NULL);
|
|
+ r = rtnl_set_link_name(&event->rtnl, ifindex, event->name, event->altnames);
|
|
if (r < 0) {
|
|
if (r == -EBUSY) {
|
|
log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
|
|
@@ -1011,6 +1009,35 @@ revert:
|
|
return r;
|
|
}
|
|
|
|
+static int assign_altnames(UdevEvent *event) {
|
|
+ sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
|
+ int ifindex, r;
|
|
+ const char *s;
|
|
+
|
|
+ if (strv_isempty(event->altnames))
|
|
+ return 0;
|
|
+
|
|
+ r = sd_device_get_ifindex(dev, &ifindex);
|
|
+ if (r == -ENOENT)
|
|
+ return 0; /* Device is not a network interface. */
|
|
+ if (r < 0)
|
|
+ return log_device_warning_errno(dev, r, "Failed to get ifindex: %m");
|
|
+
|
|
+ r = sd_device_get_sysname(dev, &s);
|
|
+ if (r < 0)
|
|
+ return log_device_warning_errno(dev, r, "Failed to get sysname: %m");
|
|
+
|
|
+ /* Filter out the current interface name. */
|
|
+ strv_remove(event->altnames, s);
|
|
+
|
|
+ r = rtnl_append_link_alternative_names(&event->rtnl, ifindex, event->altnames);
|
|
+ if (r < 0)
|
|
+ log_device_full_errno(dev, r == -EOPNOTSUPP ? LOG_DEBUG : LOG_WARNING, r,
|
|
+ "Could not set AlternativeName= or apply AlternativeNamesPolicy=, ignoring: %m");
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int update_devnode(UdevEvent *event) {
|
|
sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
|
int r;
|
|
@@ -1163,9 +1190,13 @@ int udev_event_execute_rules(
|
|
|
|
DEVICE_TRACE_POINT(rules_finished, dev);
|
|
|
|
- r = rename_netif(event);
|
|
- if (r < 0)
|
|
- return r;
|
|
+ if (action == SD_DEVICE_ADD) {
|
|
+ r = rename_netif(event);
|
|
+ if (r < 0)
|
|
+ return r;
|
|
+ if (r == 0)
|
|
+ (void) assign_altnames(event);
|
|
+ }
|
|
|
|
r = update_devnode(event);
|
|
if (r < 0)
|
|
diff --git a/src/udev/udev-event.h b/src/udev/udev-event.h
|
|
index 74d065ce23..13bd85dcf7 100644
|
|
--- a/src/udev/udev-event.h
|
|
+++ b/src/udev/udev-event.h
|
|
@@ -23,6 +23,7 @@ typedef struct UdevEvent {
|
|
sd_device *dev_parent;
|
|
sd_device *dev_db_clone;
|
|
char *name;
|
|
+ char **altnames;
|
|
char *program_result;
|
|
mode_t mode;
|
|
uid_t uid;
|