Skip to content

Commit 12b6f70

Browse files
NicolasDichtelPaolo Abeni
authored andcommitted
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 <[email protected]> Reviewed-by: Eric Dumazet <[email protected]> Reviewed-by: Kuniyuki Iwashima <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 4754aff commit 12b6f70

File tree

3 files changed

+38
-12
lines changed

3 files changed

+38
-12
lines changed

include/linux/netdevice.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4191,12 +4191,13 @@ int dev_change_flags(struct net_device *dev, unsigned int flags,
41914191
int dev_set_alias(struct net_device *, const char *, size_t);
41924192
int dev_get_alias(const struct net_device *, char *, size_t);
41934193
int __dev_change_net_namespace(struct net_device *dev, struct net *net,
4194-
const char *pat, int new_ifindex);
4194+
const char *pat, int new_ifindex,
4195+
struct netlink_ext_ack *extack);
41954196
static inline
41964197
int dev_change_net_namespace(struct net_device *dev, struct net *net,
41974198
const char *pat)
41984199
{
4199-
return __dev_change_net_namespace(dev, net, pat, 0);
4200+
return __dev_change_net_namespace(dev, net, pat, 0, NULL);
42004201
}
42014202
int __dev_set_mtu(struct net_device *, int);
42024203
int dev_set_mtu(struct net_device *, int);

net/core/dev.c

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12131,6 +12131,7 @@ EXPORT_SYMBOL(unregister_netdev);
1213112131
* is already taken in the destination network namespace.
1213212132
* @new_ifindex: If not zero, specifies device index in the target
1213312133
* namespace.
12134+
* @extack: netlink extended ack
1213412135
*
1213512136
* This function shuts down a device interface and moves it
1213612137
* to a new network namespace. On success 0 is returned, on
@@ -12140,7 +12141,8 @@ EXPORT_SYMBOL(unregister_netdev);
1214012141
*/
1214112142

1214212143
int __dev_change_net_namespace(struct net_device *dev, struct net *net,
12143-
const char *pat, int new_ifindex)
12144+
const char *pat, int new_ifindex,
12145+
struct netlink_ext_ack *extack)
1214412146
{
1214512147
struct netdev_name_node *name_node;
1214612148
struct net *net_old = dev_net(dev);
@@ -12151,12 +12153,16 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
1215112153

1215212154
/* Don't allow namespace local devices to be moved. */
1215312155
err = -EINVAL;
12154-
if (dev->netns_immutable)
12156+
if (dev->netns_immutable) {
12157+
NL_SET_ERR_MSG(extack, "The interface netns is immutable");
1215512158
goto out;
12159+
}
1215612160

1215712161
/* Ensure the device has been registered */
12158-
if (dev->reg_state != NETREG_REGISTERED)
12162+
if (dev->reg_state != NETREG_REGISTERED) {
12163+
NL_SET_ERR_MSG(extack, "The interface isn't registered");
1215912164
goto out;
12165+
}
1216012166

1216112167
/* Get out if there is nothing todo */
1216212168
err = 0;
@@ -12169,30 +12175,49 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
1216912175
err = -EEXIST;
1217012176
if (netdev_name_in_use(net, dev->name)) {
1217112177
/* We get here if we can't use the current device name */
12172-
if (!pat)
12178+
if (!pat) {
12179+
NL_SET_ERR_MSG(extack,
12180+
"An interface with the same name exists in the target netns");
1217312181
goto out;
12182+
}
1217412183
err = dev_prep_valid_name(net, dev, pat, new_name, EEXIST);
12175-
if (err < 0)
12184+
if (err < 0) {
12185+
NL_SET_ERR_MSG_FMT(extack,
12186+
"Unable to use '%s' for the new interface name in the target netns",
12187+
pat);
1217612188
goto out;
12189+
}
1217712190
}
1217812191
/* Check that none of the altnames conflicts. */
1217912192
err = -EEXIST;
12180-
netdev_for_each_altname(dev, name_node)
12181-
if (netdev_name_in_use(net, name_node->name))
12193+
netdev_for_each_altname(dev, name_node) {
12194+
if (netdev_name_in_use(net, name_node->name)) {
12195+
NL_SET_ERR_MSG_FMT(extack,
12196+
"An interface with the altname %s exists in the target netns",
12197+
name_node->name);
1218212198
goto out;
12199+
}
12200+
}
1218312201

1218412202
/* Check that new_ifindex isn't used yet. */
1218512203
if (new_ifindex) {
1218612204
err = dev_index_reserve(net, new_ifindex);
12187-
if (err < 0)
12205+
if (err < 0) {
12206+
NL_SET_ERR_MSG_FMT(extack,
12207+
"The ifindex %d is not available in the target netns",
12208+
new_ifindex);
1218812209
goto out;
12210+
}
1218912211
} else {
1219012212
/* If there is an ifindex conflict assign a new one */
1219112213
err = dev_index_reserve(net, dev->ifindex);
1219212214
if (err == -EBUSY)
1219312215
err = dev_index_reserve(net, 0);
12194-
if (err < 0)
12216+
if (err < 0) {
12217+
NL_SET_ERR_MSG(extack,
12218+
"Unable to allocate a new ifindex in the target netns");
1219512219
goto out;
12220+
}
1219612221
new_ifindex = err;
1219712222
}
1219812223

net/core/rtnetlink.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3028,7 +3028,7 @@ static int do_setlink(const struct sk_buff *skb, struct net_device *dev,
30283028

30293029
new_ifindex = nla_get_s32_default(tb[IFLA_NEW_IFINDEX], 0);
30303030

3031-
err = __dev_change_net_namespace(dev, tgt_net, pat, new_ifindex);
3031+
err = __dev_change_net_namespace(dev, tgt_net, pat, new_ifindex, extack);
30323032
if (err)
30333033
goto errout;
30343034

0 commit comments

Comments
 (0)