aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/rtnetlink.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2007-09-12 07:57:04 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:49:13 -0400
commitd8a5ec672768c3cf4d51d7a63fc071520afa1617 (patch)
tree16401b29340732fa37de7899fc44db6b682e20d7 /net/core/rtnetlink.c
parentce286d327341295f58d89864d746a524287cfdf9 (diff)
[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>
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r--net/core/rtnetlink.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 44f91bb1ae8d..1b9c32d79917 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -35,6 +35,7 @@
35#include <linux/security.h> 35#include <linux/security.h>
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/if_addr.h> 37#include <linux/if_addr.h>
38#include <linux/nsproxy.h>
38 39
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
40#include <asm/system.h> 41#include <asm/system.h>
@@ -727,6 +728,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
727 [IFLA_WEIGHT] = { .type = NLA_U32 }, 728 [IFLA_WEIGHT] = { .type = NLA_U32 },
728 [IFLA_OPERSTATE] = { .type = NLA_U8 }, 729 [IFLA_OPERSTATE] = { .type = NLA_U8 },
729 [IFLA_LINKMODE] = { .type = NLA_U8 }, 730 [IFLA_LINKMODE] = { .type = NLA_U8 },
731 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
730}; 732};
731 733
732static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { 734static 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] = {
734 [IFLA_INFO_DATA] = { .type = NLA_NESTED }, 736 [IFLA_INFO_DATA] = { .type = NLA_NESTED },
735}; 737};
736 738
739static struct net *get_net_ns_by_pid(pid_t pid)
740{
741 struct task_struct *tsk;
742 struct net *net;
743
744 /* Lookup the network namespace */
745 net = ERR_PTR(-ESRCH);
746 rcu_read_lock();
747 tsk = find_task_by_pid(pid);
748 if (tsk) {
749 task_lock(tsk);
750 if (tsk->nsproxy)
751 net = get_net(tsk->nsproxy->net_ns);
752 task_unlock(tsk);
753 }
754 rcu_read_unlock();
755 return net;
756}
757
737static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, 758static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
738 struct nlattr **tb, char *ifname, int modified) 759 struct nlattr **tb, char *ifname, int modified)
739{ 760{
740 int send_addr_notify = 0; 761 int send_addr_notify = 0;
741 int err; 762 int err;
742 763
764 if (tb[IFLA_NET_NS_PID]) {
765 struct net *net;
766 net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID]));
767 if (IS_ERR(net)) {
768 err = PTR_ERR(net);
769 goto errout;
770 }
771 err = dev_change_net_namespace(dev, net, ifname);
772 put_net(net);
773 if (err)
774 goto errout;
775 modified = 1;
776 }
777
743 if (tb[IFLA_MAP]) { 778 if (tb[IFLA_MAP]) {
744 struct rtnl_link_ifmap *u_map; 779 struct rtnl_link_ifmap *u_map;
745 struct ifmap k_map; 780 struct ifmap k_map;