mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-26 03:52:41 +00:00
net: plumb extack in __dev_change_net_namespace()
It could be hard to understand why the netlink command fails. For example, if dev->netns_immutable is set, the error is "Invalid argument". Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
committed by
Paolo Abeni
parent
4754affe0b
commit
12b6f7069b
@@ -12131,6 +12131,7 @@ EXPORT_SYMBOL(unregister_netdev);
|
||||
* is already taken in the destination network namespace.
|
||||
* @new_ifindex: If not zero, specifies device index in the target
|
||||
* namespace.
|
||||
* @extack: netlink extended ack
|
||||
*
|
||||
* This function shuts down a device interface and moves it
|
||||
* to a new network namespace. On success 0 is returned, on
|
||||
@@ -12140,7 +12141,8 @@ EXPORT_SYMBOL(unregister_netdev);
|
||||
*/
|
||||
|
||||
int __dev_change_net_namespace(struct net_device *dev, struct net *net,
|
||||
const char *pat, int new_ifindex)
|
||||
const char *pat, int new_ifindex,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct netdev_name_node *name_node;
|
||||
struct net *net_old = dev_net(dev);
|
||||
@@ -12151,12 +12153,16 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
|
||||
|
||||
/* Don't allow namespace local devices to be moved. */
|
||||
err = -EINVAL;
|
||||
if (dev->netns_immutable)
|
||||
if (dev->netns_immutable) {
|
||||
NL_SET_ERR_MSG(extack, "The interface netns is immutable");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Ensure the device has been registered */
|
||||
if (dev->reg_state != NETREG_REGISTERED)
|
||||
if (dev->reg_state != NETREG_REGISTERED) {
|
||||
NL_SET_ERR_MSG(extack, "The interface isn't registered");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Get out if there is nothing todo */
|
||||
err = 0;
|
||||
@@ -12169,30 +12175,49 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
|
||||
err = -EEXIST;
|
||||
if (netdev_name_in_use(net, dev->name)) {
|
||||
/* We get here if we can't use the current device name */
|
||||
if (!pat)
|
||||
if (!pat) {
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"An interface with the same name exists in the target netns");
|
||||
goto out;
|
||||
}
|
||||
err = dev_prep_valid_name(net, dev, pat, new_name, EEXIST);
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
NL_SET_ERR_MSG_FMT(extack,
|
||||
"Unable to use '%s' for the new interface name in the target netns",
|
||||
pat);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* Check that none of the altnames conflicts. */
|
||||
err = -EEXIST;
|
||||
netdev_for_each_altname(dev, name_node)
|
||||
if (netdev_name_in_use(net, name_node->name))
|
||||
netdev_for_each_altname(dev, name_node) {
|
||||
if (netdev_name_in_use(net, name_node->name)) {
|
||||
NL_SET_ERR_MSG_FMT(extack,
|
||||
"An interface with the altname %s exists in the target netns",
|
||||
name_node->name);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that new_ifindex isn't used yet. */
|
||||
if (new_ifindex) {
|
||||
err = dev_index_reserve(net, new_ifindex);
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
NL_SET_ERR_MSG_FMT(extack,
|
||||
"The ifindex %d is not available in the target netns",
|
||||
new_ifindex);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* If there is an ifindex conflict assign a new one */
|
||||
err = dev_index_reserve(net, dev->ifindex);
|
||||
if (err == -EBUSY)
|
||||
err = dev_index_reserve(net, 0);
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"Unable to allocate a new ifindex in the target netns");
|
||||
goto out;
|
||||
}
|
||||
new_ifindex = err;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user