mirror of
https://github.com/systemd/systemd.git
synced 2025-01-24 06:04:05 +03:00
sd-netlink: make rtnl_set_link_name() optionally append alternative names
This commit is contained in:
parent
cd941e6596
commit
8182445500
@ -11,44 +11,93 @@
|
||||
#include "process-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||
static int 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;
|
||||
bool altname_deleted = false;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(ifindex > 0);
|
||||
assert(name);
|
||||
|
||||
if (!ifname_valid(name))
|
||||
/* Assign the requested name. */
|
||||
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_message_append_string(message, IFLA_IFNAME, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_netlink_call(*rtnl, message, 0, NULL);
|
||||
}
|
||||
|
||||
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name, char* const *alternative_names) {
|
||||
_cleanup_strv_free_ char **original_altnames = NULL, **new_altnames = NULL;
|
||||
bool altname_deleted = false;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(ifindex > 0);
|
||||
|
||||
if (isempty(name) && strv_isempty(alternative_names))
|
||||
return 0;
|
||||
|
||||
if (name && !ifname_valid(name))
|
||||
return -EINVAL;
|
||||
|
||||
r = rtnl_get_link_alternative_names(rtnl, ifindex, &alternative_names);
|
||||
/* If the requested name is already assigned as an alternative name, then first drop it. */
|
||||
r = rtnl_get_link_alternative_names(rtnl, ifindex, &original_altnames);
|
||||
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 log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
|
||||
name, ifindex);
|
||||
if (name) {
|
||||
if (strv_contains(original_altnames, name)) {
|
||||
r = rtnl_delete_link_alternative_names(rtnl, ifindex, STRV_MAKE(name));
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
|
||||
name, ifindex);
|
||||
|
||||
altname_deleted = true;
|
||||
altname_deleted = true;
|
||||
}
|
||||
|
||||
r = set_link_name(rtnl, ifindex, name);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
/* Filter out already assigned names from requested alternative names. Also, dedup the request. */
|
||||
STRV_FOREACH(a, alternative_names) {
|
||||
if (streq_ptr(name, *a))
|
||||
continue;
|
||||
|
||||
r = sd_netlink_message_append_string(message, IFLA_IFNAME, name);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
if (strv_contains(original_altnames, *a))
|
||||
continue;
|
||||
|
||||
r = sd_netlink_call(*rtnl, message, 0, NULL);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
if (strv_contains(new_altnames, *a))
|
||||
continue;
|
||||
|
||||
if (!ifname_valid_full(*a, IFNAME_VALID_ALTERNATIVE))
|
||||
continue;
|
||||
|
||||
r = strv_extend(&new_altnames, *a);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
strv_sort(new_altnames);
|
||||
|
||||
/* Finally, assign alternative names. */
|
||||
r = rtnl_set_link_alternative_names(rtnl, ifindex, new_altnames);
|
||||
if (r == -EEXIST) /* Already assigned to another interface? */
|
||||
STRV_FOREACH(a, new_altnames) {
|
||||
r = rtnl_set_link_alternative_names(rtnl, ifindex, STRV_MAKE(*a));
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to assign '%s' as an alternative name on network interface %i, ignoring: %m",
|
||||
*a, ifindex);
|
||||
}
|
||||
else if (r < 0)
|
||||
log_debug_errno(r, "Failed to assign alternative names on network interface %i, ignoring: %m", ifindex);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -28,7 +28,10 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(MultipathRoute*, multipath_route_free);
|
||||
|
||||
int multipath_route_dup(const MultipathRoute *m, MultipathRoute **ret);
|
||||
|
||||
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
|
||||
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name, char* const* alternative_names);
|
||||
static inline int rtnl_append_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names) {
|
||||
return rtnl_set_link_name(rtnl, ifindex, NULL, alternative_names);
|
||||
}
|
||||
int rtnl_set_link_properties(
|
||||
sd_netlink **rtnl,
|
||||
int ifindex,
|
||||
|
@ -662,12 +662,13 @@ TEST(rtnl_set_link_name) {
|
||||
assert_se(strv_contains(alternative_names, "testlongalternativename"));
|
||||
assert_se(strv_contains(alternative_names, "test-shortname"));
|
||||
|
||||
assert_se(rtnl_set_link_name(&rtnl, ifindex, "testlongalternativename") == -EINVAL);
|
||||
assert_se(rtnl_set_link_name(&rtnl, ifindex, "test-shortname") >= 0);
|
||||
assert_se(rtnl_set_link_name(&rtnl, ifindex, "testlongalternativename", NULL) == -EINVAL);
|
||||
assert_se(rtnl_set_link_name(&rtnl, ifindex, "test-shortname", STRV_MAKE("testlongalternativename", "test-shortname", "test-additional-name")) >= 0);
|
||||
|
||||
alternative_names = strv_free(alternative_names);
|
||||
assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0);
|
||||
assert_se(strv_contains(alternative_names, "testlongalternativename"));
|
||||
assert_se(strv_contains(alternative_names, "test-additional-name"));
|
||||
assert_se(!strv_contains(alternative_names, "test-shortname"));
|
||||
|
||||
assert_se(rtnl_delete_link_alternative_names(&rtnl, ifindex, STRV_MAKE("testlongalternativename")) >= 0);
|
||||
@ -675,6 +676,7 @@ TEST(rtnl_set_link_name) {
|
||||
alternative_names = strv_free(alternative_names);
|
||||
assert_se(rtnl_get_link_alternative_names(&rtnl, ifindex, &alternative_names) >= 0);
|
||||
assert_se(!strv_contains(alternative_names, "testlongalternativename"));
|
||||
assert_se(strv_contains(alternative_names, "test-additional-name"));
|
||||
assert_se(!strv_contains(alternative_names, "test-shortname"));
|
||||
}
|
||||
|
||||
|
@ -976,7 +976,7 @@ static int rename_netif(UdevEvent *event) {
|
||||
goto revert;
|
||||
}
|
||||
|
||||
r = rtnl_set_link_name(&event->rtnl, ifindex, event->name);
|
||||
r = rtnl_set_link_name(&event->rtnl, ifindex, event->name, NULL);
|
||||
if (r < 0) {
|
||||
if (r == -EBUSY) {
|
||||
log_device_info(dev, "Network interface '%s' is already up, cannot rename to '%s'.",
|
||||
|
Loading…
x
Reference in New Issue
Block a user