summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-05-16 12:28:23 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2023-05-16 16:37:31 +0900
commit9094ae52caca0c19ff6abdbd95d17d8e401ea3b1 (patch)
treee14986e9af9d1876ed445708b57e779e76dfd372
parent81824455008070253c62bf5c27187028ba8e7e99 (diff)
downloadsystemd-9094ae52caca0c19ff6abdbd95d17d8e401ea3b1.tar.gz
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.
-rw-r--r--src/udev/net/link-config.c37
-rw-r--r--src/udev/net/link-config.h1
-rw-r--r--src/udev/udev-builtin-net_setup_link.c2
-rw-r--r--src/udev/udev-event.c45
-rw-r--r--src/udev/udev-event.h1
5 files changed, 55 insertions, 31 deletions
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 28571319fc..b554a6827d 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -365,6 +365,7 @@ Link *link_free(Link *link) {
sd_device_unref(link->device);
free(link->kind);
free(link->driver);
+ strv_free(link->altnames);
return mfree(link);
}
@@ -793,19 +794,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);
@@ -843,22 +847,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, &current_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;
}
@@ -960,7 +949,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 ed0896e9de..713d41040a 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 84a0a6ef3f..5bc965f6d8 100644
--- a/src/udev/udev-builtin-net_setup_link.c
+++ b/src/udev/udev-builtin-net_setup_link.c
@@ -52,6 +52,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);
+
STRV_FOREACH(d, link->config->dropins) {
_cleanup_free_ char *escaped = NULL;
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 7f6d8e4a75..b3cdb32a63 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -87,6 +87,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);
}
@@ -914,9 +915,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. */
@@ -976,7 +974,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'.",
@@ -1007,6 +1005,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;
@@ -1148,9 +1175,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 c54c7891b6..b99559ca2e 100644
--- a/src/udev/udev-event.h
+++ b/src/udev/udev-event.h
@@ -22,6 +22,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;