aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/can/dev.c2
-rw-r--r--drivers/net/macvlan.c4
-rw-r--r--drivers/net/veth.c15
-rw-r--r--include/net/rtnetlink.h8
-rw-r--r--net/8021q/vlan_netlink.c4
-rw-r--r--net/core/rtnetlink.c38
-rw-r--r--net/ipv4/ip_gre.c2
7 files changed, 50 insertions, 23 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index c3db111d2ff5..5fe34d64ca2a 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -674,7 +674,7 @@ nla_put_failure:
674 return -EMSGSIZE; 674 return -EMSGSIZE;
675} 675}
676 676
677static int can_newlink(struct net_device *dev, 677static int can_newlink(struct net *src_net, struct net_device *dev,
678 struct nlattr *tb[], struct nlattr *data[]) 678 struct nlattr *tb[], struct nlattr *data[])
679{ 679{
680 return -EOPNOTSUPP; 680 return -EOPNOTSUPP;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 20b7707f38ef..d7dba3f6f763 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -504,7 +504,7 @@ static int macvlan_get_tx_queues(struct net *net,
504 return 0; 504 return 0;
505} 505}
506 506
507static int macvlan_newlink(struct net_device *dev, 507static int macvlan_newlink(struct net *src_net, struct net_device *dev,
508 struct nlattr *tb[], struct nlattr *data[]) 508 struct nlattr *tb[], struct nlattr *data[])
509{ 509{
510 struct macvlan_dev *vlan = netdev_priv(dev); 510 struct macvlan_dev *vlan = netdev_priv(dev);
@@ -515,7 +515,7 @@ static int macvlan_newlink(struct net_device *dev,
515 if (!tb[IFLA_LINK]) 515 if (!tb[IFLA_LINK])
516 return -EINVAL; 516 return -EINVAL;
517 517
518 lowerdev = __dev_get_by_index(dev_net(dev), nla_get_u32(tb[IFLA_LINK])); 518 lowerdev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
519 if (lowerdev == NULL) 519 if (lowerdev == NULL)
520 return -ENODEV; 520 return -ENODEV;
521 521
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 9bed694cd215..2d657f2314cb 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -340,7 +340,7 @@ static int veth_validate(struct nlattr *tb[], struct nlattr *data[])
340 340
341static struct rtnl_link_ops veth_link_ops; 341static struct rtnl_link_ops veth_link_ops;
342 342
343static int veth_newlink(struct net_device *dev, 343static int veth_newlink(struct net *src_net, struct net_device *dev,
344 struct nlattr *tb[], struct nlattr *data[]) 344 struct nlattr *tb[], struct nlattr *data[])
345{ 345{
346 int err; 346 int err;
@@ -348,6 +348,7 @@ static int veth_newlink(struct net_device *dev,
348 struct veth_priv *priv; 348 struct veth_priv *priv;
349 char ifname[IFNAMSIZ]; 349 char ifname[IFNAMSIZ];
350 struct nlattr *peer_tb[IFLA_MAX + 1], **tbp; 350 struct nlattr *peer_tb[IFLA_MAX + 1], **tbp;
351 struct net *net;
351 352
352 /* 353 /*
353 * create and register peer first 354 * create and register peer first
@@ -380,14 +381,22 @@ static int veth_newlink(struct net_device *dev,
380 else 381 else
381 snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d"); 382 snprintf(ifname, IFNAMSIZ, DRV_NAME "%%d");
382 383
383 peer = rtnl_create_link(dev_net(dev), ifname, &veth_link_ops, tbp); 384 net = rtnl_link_get_net(src_net, tbp);
384 if (IS_ERR(peer)) 385 if (IS_ERR(net))
386 return PTR_ERR(net);
387
388 peer = rtnl_create_link(src_net, net, ifname, &veth_link_ops, tbp);
389 if (IS_ERR(peer)) {
390 put_net(net);
385 return PTR_ERR(peer); 391 return PTR_ERR(peer);
392 }
386 393
387 if (tbp[IFLA_ADDRESS] == NULL) 394 if (tbp[IFLA_ADDRESS] == NULL)
388 random_ether_addr(peer->dev_addr); 395 random_ether_addr(peer->dev_addr);
389 396
390 err = register_netdevice(peer); 397 err = register_netdevice(peer);
398 put_net(net);
399 net = NULL;
391 if (err < 0) 400 if (err < 0)
392 goto err_register_peer; 401 goto err_register_peer;
393 402
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index cd5af1f508f2..48d3efcb0880 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -55,7 +55,8 @@ struct rtnl_link_ops {
55 int (*validate)(struct nlattr *tb[], 55 int (*validate)(struct nlattr *tb[],
56 struct nlattr *data[]); 56 struct nlattr *data[]);
57 57
58 int (*newlink)(struct net_device *dev, 58 int (*newlink)(struct net *src_net,
59 struct net_device *dev,
59 struct nlattr *tb[], 60 struct nlattr *tb[],
60 struct nlattr *data[]); 61 struct nlattr *data[]);
61 int (*changelink)(struct net_device *dev, 62 int (*changelink)(struct net_device *dev,
@@ -83,8 +84,9 @@ extern void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops);
83extern int rtnl_link_register(struct rtnl_link_ops *ops); 84extern int rtnl_link_register(struct rtnl_link_ops *ops);
84extern void rtnl_link_unregister(struct rtnl_link_ops *ops); 85extern void rtnl_link_unregister(struct rtnl_link_ops *ops);
85 86
86extern struct net_device *rtnl_create_link(struct net *net, char *ifname, 87extern struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]);
87 const struct rtnl_link_ops *ops, struct nlattr *tb[]); 88extern struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
89 char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]);
88extern const struct nla_policy ifla_policy[IFLA_MAX+1]; 90extern const struct nla_policy ifla_policy[IFLA_MAX+1];
89 91
90#define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind) 92#define MODULE_ALIAS_RTNL_LINK(kind) MODULE_ALIAS("rtnl-link-" kind)
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index a91504850195..3c9cf6a8e7fb 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -119,7 +119,7 @@ static int vlan_get_tx_queues(struct net *net,
119 return 0; 119 return 0;
120} 120}
121 121
122static int vlan_newlink(struct net_device *dev, 122static int vlan_newlink(struct net *src_net, struct net_device *dev,
123 struct nlattr *tb[], struct nlattr *data[]) 123 struct nlattr *tb[], struct nlattr *data[])
124{ 124{
125 struct vlan_dev_info *vlan = vlan_dev_info(dev); 125 struct vlan_dev_info *vlan = vlan_dev_info(dev);
@@ -131,7 +131,7 @@ static int vlan_newlink(struct net_device *dev,
131 131
132 if (!tb[IFLA_LINK]) 132 if (!tb[IFLA_LINK])
133 return -EINVAL; 133 return -EINVAL;
134 real_dev = __dev_get_by_index(dev_net(dev), nla_get_u32(tb[IFLA_LINK])); 134 real_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
135 if (!real_dev) 135 if (!real_dev)
136 return -ENODEV; 136 return -ENODEV;
137 137
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}
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 71a3242fb7d0..a7de9e3a8f18 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1483,7 +1483,7 @@ static void ipgre_tap_setup(struct net_device *dev)
1483 dev->features |= NETIF_F_NETNS_LOCAL; 1483 dev->features |= NETIF_F_NETNS_LOCAL;
1484} 1484}
1485 1485
1486static int ipgre_newlink(struct net_device *dev, struct nlattr *tb[], 1486static int ipgre_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[],
1487 struct nlattr *data[]) 1487 struct nlattr *data[])
1488{ 1488{
1489 struct ip_tunnel *nt; 1489 struct ip_tunnel *nt;