[NET]: netlink support for moving devices between network namespaces.
The simplest thing to implement is moving network devices between namespaces. However with the same attribute IFLA_NET_NS_PID we can easily implement creating devices in the destination network namespace as well. However that is a little bit trickier so this patch sticks to what is simple and easy. A pid is used to identify a process that happens to be a member of the network namespace we want to move the network device to. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
ce286d3273
Коммит
d8a5ec6727
|
@ -78,6 +78,7 @@ enum
|
||||||
IFLA_LINKMODE,
|
IFLA_LINKMODE,
|
||||||
IFLA_LINKINFO,
|
IFLA_LINKINFO,
|
||||||
#define IFLA_LINKINFO IFLA_LINKINFO
|
#define IFLA_LINKINFO IFLA_LINKINFO
|
||||||
|
IFLA_NET_NS_PID,
|
||||||
__IFLA_MAX
|
__IFLA_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/if_addr.h>
|
#include <linux/if_addr.h>
|
||||||
|
#include <linux/nsproxy.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
@ -727,6 +728,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
|
||||||
[IFLA_WEIGHT] = { .type = NLA_U32 },
|
[IFLA_WEIGHT] = { .type = NLA_U32 },
|
||||||
[IFLA_OPERSTATE] = { .type = NLA_U8 },
|
[IFLA_OPERSTATE] = { .type = NLA_U8 },
|
||||||
[IFLA_LINKMODE] = { .type = NLA_U8 },
|
[IFLA_LINKMODE] = { .type = NLA_U8 },
|
||||||
|
[IFLA_NET_NS_PID] = { .type = NLA_U32 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
|
static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
|
||||||
|
@ -734,12 +736,45 @@ static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
|
||||||
[IFLA_INFO_DATA] = { .type = NLA_NESTED },
|
[IFLA_INFO_DATA] = { .type = NLA_NESTED },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct net *get_net_ns_by_pid(pid_t pid)
|
||||||
|
{
|
||||||
|
struct task_struct *tsk;
|
||||||
|
struct net *net;
|
||||||
|
|
||||||
|
/* Lookup the network namespace */
|
||||||
|
net = ERR_PTR(-ESRCH);
|
||||||
|
rcu_read_lock();
|
||||||
|
tsk = find_task_by_pid(pid);
|
||||||
|
if (tsk) {
|
||||||
|
task_lock(tsk);
|
||||||
|
if (tsk->nsproxy)
|
||||||
|
net = get_net(tsk->nsproxy->net_ns);
|
||||||
|
task_unlock(tsk);
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
return net;
|
||||||
|
}
|
||||||
|
|
||||||
static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
|
static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
|
||||||
struct nlattr **tb, char *ifname, int modified)
|
struct nlattr **tb, char *ifname, int modified)
|
||||||
{
|
{
|
||||||
int send_addr_notify = 0;
|
int send_addr_notify = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (tb[IFLA_NET_NS_PID]) {
|
||||||
|
struct net *net;
|
||||||
|
net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID]));
|
||||||
|
if (IS_ERR(net)) {
|
||||||
|
err = PTR_ERR(net);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
err = dev_change_net_namespace(dev, net, ifname);
|
||||||
|
put_net(net);
|
||||||
|
if (err)
|
||||||
|
goto errout;
|
||||||
|
modified = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (tb[IFLA_MAP]) {
|
if (tb[IFLA_MAP]) {
|
||||||
struct rtnl_link_ifmap *u_map;
|
struct rtnl_link_ifmap *u_map;
|
||||||
struct ifmap k_map;
|
struct ifmap k_map;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче