aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@aristanetworks.com>2009-11-08 03:53:51 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-08 03:53:51 -0500
commit81adee47dfb608df3ad0b91d230fb3cef75f0060 (patch)
treee9d7a41872f84c1395e21915e5f92c05ab872e69 /net/core
parentf7a3a1d8affe563846fc17f0e7c0cc1500190c57 (diff)
net: Support specifying the network namespace upon device creation.
There is no good reason to not support userspace specifying the network namespace during device creation, and it makes it easier to create a network device and pass it to a child network namespace with a well known name. We have to be careful to ensure that the target network namespace for the new device exists through the life of the call. To keep that logic clear I have factored out the network namespace grabbing logic into rtnl_link_get_net. In addtion we need to continue to pass the source network namespace to the rtnl_link_ops.newlink method so that we can find the base device source network namespace. Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/rtnetlink.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index e2f3317f290f..33148a568199 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -733,6 +733,20 @@ static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
733 [IFLA_INFO_DATA] = { .type = NLA_NESTED }, 733 [IFLA_INFO_DATA] = { .type = NLA_NESTED },
734}; 734};
735 735
736struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
737{
738 struct net *net;
739 /* Examine the link attributes and figure out which
740 * network namespace we are talking about.
741 */
742 if (tb[IFLA_NET_NS_PID])
743 net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID]));
744 else
745 net = get_net(src_net);
746 return net;
747}
748EXPORT_SYMBOL(rtnl_link_get_net);
749
736static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) 750static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
737{ 751{
738 if (dev) { 752 if (dev) {
@@ -756,8 +770,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
756 int err; 770 int err;
757 771
758 if (tb[IFLA_NET_NS_PID]) { 772 if (tb[IFLA_NET_NS_PID]) {
759 struct net *net; 773 struct net *net = rtnl_link_get_net(dev_net(dev), tb);
760 net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID]));
761 if (IS_ERR(net)) { 774 if (IS_ERR(net)) {
762 err = PTR_ERR(net); 775 err = PTR_ERR(net);
763 goto errout; 776 goto errout;
@@ -976,8 +989,8 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
976 return 0; 989 return 0;
977} 990}
978 991
979struct net_device *rtnl_create_link(struct net *net, char *ifname, 992struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
980 const struct rtnl_link_ops *ops, struct nlattr *tb[]) 993 char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[])
981{ 994{
982 int err; 995 int err;
983 struct net_device *dev; 996 struct net_device *dev;
@@ -985,7 +998,7 @@ struct net_device *rtnl_create_link(struct net *net, char *ifname,
985 unsigned int real_num_queues = 1; 998 unsigned int real_num_queues = 1;
986 999
987 if (ops->get_tx_queues) { 1000 if (ops->get_tx_queues) {
988 err = ops->get_tx_queues(net, tb, &num_queues, 1001 err = ops->get_tx_queues(src_net, tb, &num_queues,
989 &real_num_queues); 1002 &real_num_queues);
990 if (err) 1003 if (err)
991 goto err; 1004 goto err;
@@ -995,16 +1008,16 @@ struct net_device *rtnl_create_link(struct net *net, char *ifname,
995 if (!dev) 1008 if (!dev)
996 goto err; 1009 goto err;
997 1010
1011 dev_net_set(dev, net);
1012 dev->rtnl_link_ops = ops;
998 dev->real_num_tx_queues = real_num_queues; 1013 dev->real_num_tx_queues = real_num_queues;
1014
999 if (strchr(dev->name, '%')) { 1015 if (strchr(dev->name, '%')) {
1000 err = dev_alloc_name(dev, dev->name); 1016 err = dev_alloc_name(dev, dev->name);
1001 if (err < 0) 1017 if (err < 0)
1002 goto err_free; 1018 goto err_free;
1003 } 1019 }
1004 1020
1005 dev_net_set(dev, net);
1006 dev->rtnl_link_ops = ops;
1007
1008 if (tb[IFLA_MTU]) 1021 if (tb[IFLA_MTU])
1009 dev->mtu = nla_get_u32(tb[IFLA_MTU]); 1022 dev->mtu = nla_get_u32(tb[IFLA_MTU]);
1010 if (tb[IFLA_ADDRESS]) 1023 if (tb[IFLA_ADDRESS])
@@ -1083,6 +1096,7 @@ replay:
1083 1096
1084 if (1) { 1097 if (1) {
1085 struct nlattr *attr[ops ? ops->maxtype + 1 : 0], **data = NULL; 1098 struct nlattr *attr[ops ? ops->maxtype + 1 : 0], **data = NULL;
1099 struct net *dest_net;
1086 1100
1087 if (ops) { 1101 if (ops) {
1088 if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) { 1102 if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
@@ -1147,17 +1161,19 @@ replay:
1147 if (!ifname[0]) 1161 if (!ifname[0])
1148 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); 1162 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
1149 1163
1150 dev = rtnl_create_link(net, ifname, ops, tb); 1164 dest_net = rtnl_link_get_net(net, tb);
1165 dev = rtnl_create_link(net, dest_net, ifname, ops, tb);
1151 1166
1152 if (IS_ERR(dev)) 1167 if (IS_ERR(dev))
1153 err = PTR_ERR(dev); 1168 err = PTR_ERR(dev);
1154 else if (ops->newlink) 1169 else if (ops->newlink)
1155 err = ops->newlink(dev, tb, data); 1170 err = ops->newlink(net, dev, tb, data);
1156 else 1171 else
1157 err = register_netdevice(dev); 1172 err = register_netdevice(dev);
1158
1159 if (err < 0 && !IS_ERR(dev)) 1173 if (err < 0 && !IS_ERR(dev))
1160 free_netdev(dev); 1174 free_netdev(dev);
1175
1176 put_net(dest_net);
1161 return err; 1177 return err;
1162 } 1178 }
1163} 1179}