aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2007-11-20 01:27:40 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:54:26 -0500
commit4b3da706bbe4613d2fe4df8df4d965954ea98964 (patch)
treeaba584cfbf5a70cfbc95ea87faebdbec5ea2c64a
parent97c53cacf00d1f5aa04adabfebcc806ca8b22b10 (diff)
[NET]: Make the netlink methods in rtnetlink handle multiple network namespaces
After the previous prep work this just consists of removing checks limiting the code to work in the initial network namespace, and updating rtmsg_ifinfo so we can generate events for devices in something other then the initial network namespace. Referring to network other network devices like the IFLA_LINK and IFLA_MASTER attributes do, gets interesting if those network devices happen to be in other network namespaces. Currently ifindex numbers are allocated globally so I have taken the path of least resistance and not still report the information even though the devices they are talking about are invisible. If applications start getting confused or when ifindex numbers become local to the network namespace we may need to do something different in the future. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Denis V. Lunev <den@openz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/core/rtnetlink.c27
1 files changed, 3 insertions, 24 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 9efaf35934f4..8c45d7e35ee9 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -708,9 +708,6 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
708 int s_idx = cb->args[0]; 708 int s_idx = cb->args[0];
709 struct net_device *dev; 709 struct net_device *dev;
710 710
711 if (net != &init_net)
712 return 0;
713
714 idx = 0; 711 idx = 0;
715 for_each_netdev(net, dev) { 712 for_each_netdev(net, dev) {
716 if (idx < s_idx) 713 if (idx < s_idx)
@@ -913,9 +910,6 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
913 struct nlattr *tb[IFLA_MAX+1]; 910 struct nlattr *tb[IFLA_MAX+1];
914 char ifname[IFNAMSIZ]; 911 char ifname[IFNAMSIZ];
915 912
916 if (net != &init_net)
917 return -EINVAL;
918
919 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); 913 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
920 if (err < 0) 914 if (err < 0)
921 goto errout; 915 goto errout;
@@ -964,9 +958,6 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
964 struct nlattr *tb[IFLA_MAX+1]; 958 struct nlattr *tb[IFLA_MAX+1];
965 int err; 959 int err;
966 960
967 if (net != &init_net)
968 return -EINVAL;
969
970 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); 961 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
971 if (err < 0) 962 if (err < 0)
972 return err; 963 return err;
@@ -1048,9 +1039,6 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1048 struct nlattr *linkinfo[IFLA_INFO_MAX+1]; 1039 struct nlattr *linkinfo[IFLA_INFO_MAX+1];
1049 int err; 1040 int err;
1050 1041
1051 if (net != &init_net)
1052 return -EINVAL;
1053
1054#ifdef CONFIG_KMOD 1042#ifdef CONFIG_KMOD
1055replay: 1043replay:
1056#endif 1044#endif
@@ -1177,9 +1165,6 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
1177 struct sk_buff *nskb; 1165 struct sk_buff *nskb;
1178 int err; 1166 int err;
1179 1167
1180 if (net != &init_net)
1181 return -EINVAL;
1182
1183 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); 1168 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
1184 if (err < 0) 1169 if (err < 0)
1185 return err; 1170 return err;
@@ -1215,13 +1200,9 @@ errout:
1215 1200
1216static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) 1201static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
1217{ 1202{
1218 struct net *net = skb->sk->sk_net;
1219 int idx; 1203 int idx;
1220 int s_idx = cb->family; 1204 int s_idx = cb->family;
1221 1205
1222 if (net != &init_net)
1223 return 0;
1224
1225 if (s_idx == 0) 1206 if (s_idx == 0)
1226 s_idx = 1; 1207 s_idx = 1;
1227 for (idx=1; idx<NPROTO; idx++) { 1208 for (idx=1; idx<NPROTO; idx++) {
@@ -1243,6 +1224,7 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
1243 1224
1244void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) 1225void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
1245{ 1226{
1227 struct net *net = dev->nd_net;
1246 struct sk_buff *skb; 1228 struct sk_buff *skb;
1247 int err = -ENOBUFS; 1229 int err = -ENOBUFS;
1248 1230
@@ -1257,10 +1239,10 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
1257 kfree_skb(skb); 1239 kfree_skb(skb);
1258 goto errout; 1240 goto errout;
1259 } 1241 }
1260 err = rtnl_notify(skb, &init_net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL); 1242 err = rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
1261errout: 1243errout:
1262 if (err < 0) 1244 if (err < 0)
1263 rtnl_set_sk_err(&init_net, RTNLGRP_LINK, err); 1245 rtnl_set_sk_err(net, RTNLGRP_LINK, err);
1264} 1246}
1265 1247
1266/* Protected by RTNL sempahore. */ 1248/* Protected by RTNL sempahore. */
@@ -1353,9 +1335,6 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
1353{ 1335{
1354 struct net_device *dev = ptr; 1336 struct net_device *dev = ptr;
1355 1337
1356 if (dev->nd_net != &init_net)
1357 return NOTIFY_DONE;
1358
1359 switch (event) { 1338 switch (event) {
1360 case NETDEV_UNREGISTER: 1339 case NETDEV_UNREGISTER:
1361 rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); 1340 rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);