82 lines
3.0 KiB
Diff
82 lines
3.0 KiB
Diff
|
From 6db267672de69d6bf4809f433cde106e11145ca8 Mon Sep 17 00:00:00 2001
|
||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||
|
Date: Fri, 17 Jul 2020 21:31:24 +0900
|
||
|
Subject: [PATCH] netlink: do not fail when new interface name is already used
|
||
|
as an alternative name
|
||
|
|
||
|
When renaming a network interface, the new name may be used as an
|
||
|
alternative name. In that case, let's swap the current name and the
|
||
|
alternative name. That is, first drop the new name from the list of
|
||
|
alternative names, then rename the interface, finally set the old name
|
||
|
as an alternative name.
|
||
|
|
||
|
(cherry picked from commit 434a34838034347f45fb9a47df55b1a36e5addfd)
|
||
|
|
||
|
Related: #1850986
|
||
|
---
|
||
|
src/libsystemd/sd-netlink/netlink-util.c | 30 +++++++++++++++++++++---
|
||
|
1 file changed, 27 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c
|
||
|
index 7f09261981..4e42ef9e26 100644
|
||
|
--- a/src/libsystemd/sd-netlink/netlink-util.c
|
||
|
+++ b/src/libsystemd/sd-netlink/netlink-util.c
|
||
|
@@ -1,23 +1,40 @@
|
||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||
|
|
||
|
+#include <net/if.h>
|
||
|
+
|
||
|
#include "sd-netlink.h"
|
||
|
|
||
|
#include "netlink-internal.h"
|
||
|
#include "netlink-util.h"
|
||
|
+#include "socket-util.h"
|
||
|
+#include "string-util.h"
|
||
|
#include "strv.h"
|
||
|
|
||
|
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
||
|
+ _cleanup_strv_free_ char **alternative_names = NULL;
|
||
|
+ char old_name[IF_NAMESIZE + 1] = {};
|
||
|
int r;
|
||
|
|
||
|
assert(rtnl);
|
||
|
assert(ifindex > 0);
|
||
|
assert(name);
|
||
|
|
||
|
- if (!*rtnl) {
|
||
|
- r = sd_netlink_open(rtnl);
|
||
|
+ if (!ifname_valid(name))
|
||
|
+ return -EINVAL;
|
||
|
+
|
||
|
+ r = rtnl_get_link_alternative_names(rtnl, ifindex, &alternative_names);
|
||
|
+ if (r < 0)
|
||
|
+ log_debug_errno(r, "Failed to get alternative names on network interface %i, ignoring: %m",
|
||
|
+ ifindex);
|
||
|
+
|
||
|
+ if (strv_contains(alternative_names, name)) {
|
||
|
+ r = rtnl_delete_link_alternative_names(rtnl, ifindex, STRV_MAKE(name));
|
||
|
if (r < 0)
|
||
|
- return r;
|
||
|
+ return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
|
||
|
+ name, ifindex);
|
||
|
+
|
||
|
+ if_indextoname(ifindex, old_name);
|
||
|
}
|
||
|
|
||
|
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
|
||
|
@@ -32,6 +49,13 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||
|
if (r < 0)
|
||
|
return r;
|
||
|
|
||
|
+ if (!isempty(old_name)) {
|
||
|
+ r = rtnl_set_link_alternative_names(rtnl, ifindex, STRV_MAKE(old_name));
|
||
|
+ if (r < 0)
|
||
|
+ log_debug_errno(r, "Failed to set '%s' as an alternative name on network interface %i, ignoring: %m",
|
||
|
+ old_name, ifindex);
|
||
|
+ }
|
||
|
+
|
||
|
return 0;
|
||
|
}
|
||
|
|