The dev list view is filled and used from here. The dev_base_list has
been replaced to the dev list view and devices can be accessed only if
the view has the device in its list. All calls from the userspace,
ioctls, netlinks and procfs, will use the network devices view instead
of the global network device list.
Replace-Subject: [Network namespace] Network devices isolation
Signed-off-by: Daniel Lezcano [EMAIL PROTECTED]
--
net/core/dev.c | 147 ++-
net/core/rtnetlink.c | 21 +--
2 files changed, 126 insertions(+), 42 deletions(-)
Index: 2.6-mm/net/core/dev.c
===
--- 2.6-mm.orig/net/core/dev.c
+++ 2.6-mm/net/core/dev.c
@@ -115,6 +115,7 @@
#include net/iw_handler.h
#include asm/current.h
#include linux/audit.h
+#include linux/net_ns.h
#include linux/dmaengine.h
/*
@@ -474,13 +475,16 @@
struct net_device *__dev_get_by_name(const char *name)
{
- struct hlist_node *p;
+ struct net_ns_dev_list *dev_list = (net_ns()-dev_list);
+ struct list_head *l, *list = dev_list-list;
+ struct net_ns_dev *db;
+ struct net_device *dev;
- hlist_for_each(p, dev_name_hash(name)) {
- struct net_device *dev
- = hlist_entry(p, struct net_device, name_hlist);
+ list_for_each(l, list) {
+ db = list_entry(l, struct net_ns_dev, list);
+ dev = db-dev;
if (!strncmp(dev-name, name, IFNAMSIZ))
- return dev;
+ return dev;
}
return NULL;
}
@@ -498,13 +502,14 @@
struct net_device *dev_get_by_name(const char *name)
{
+ struct net_ns_dev_list *dev_list = (net_ns()-dev_list);
struct net_device *dev;
- read_lock(dev_base_lock);
+ read_lock(dev_list-lock);
dev = __dev_get_by_name(name);
if (dev)
dev_hold(dev);
- read_unlock(dev_base_lock);
+ read_unlock(dev_list-lock);
return dev;
}
@@ -521,11 +526,14 @@
struct net_device *__dev_get_by_index(int ifindex)
{
- struct hlist_node *p;
+ struct net_ns_dev_list *dev_list = (net_ns()-dev_list);
+ struct list_head *l, *list = dev_list-list;
+ struct net_ns_dev *db;
+ struct net_device *dev;
- hlist_for_each(p, dev_index_hash(ifindex)) {
- struct net_device *dev
- = hlist_entry(p, struct net_device, index_hlist);
+ list_for_each(l, list) {
+ db = list_entry(l, struct net_ns_dev, list);
+ dev = db-dev;
if (dev-ifindex == ifindex)
return dev;
}
@@ -545,13 +553,14 @@
struct net_device *dev_get_by_index(int ifindex)
{
+ struct net_ns_dev_list *dev_list = (net_ns()-dev_list);
struct net_device *dev;
- read_lock(dev_base_lock);
+ read_lock(dev_list-lock);
dev = __dev_get_by_index(ifindex);
if (dev)
dev_hold(dev);
- read_unlock(dev_base_lock);
+ read_unlock(dev_list-lock);
return dev;
}
@@ -571,14 +580,24 @@
struct net_device *dev_getbyhwaddr(unsigned short type, char *ha)
{
- struct net_device *dev;
+ struct net_ns_dev_list *dev_list = (net_ns()-dev_list);
+ struct list_head *l, *list = dev_list-list;
+ struct net_ns_dev *db;
+ struct net_device *dev = NULL;
ASSERT_RTNL();
- for (dev = dev_base; dev; dev = dev-next)
+ read_lock(dev_list-lock);
+ list_for_each(l, list) {
+ db = list_entry(l, struct net_ns_dev, list);
+ dev = db-dev;
if (dev-type == type
!memcmp(dev-dev_addr, ha, dev-addr_len))
- break;
+ goto out;
+ }
+ dev = NULL;
+out:
+ read_unlock(dev_list-lock);
return dev;
}
@@ -586,15 +605,25 @@
struct net_device *dev_getfirstbyhwtype(unsigned short type)
{
+ struct net_ns_dev_list *dev_list = (net_ns()-dev_list);
+ struct list_head *l, *list = dev_list-list;
+ struct net_ns_dev *db;
struct net_device *dev;
rtnl_lock();
- for (dev = dev_base; dev; dev = dev-next) {
+
+ read_lock(dev_list-lock);
+ list_for_each(l, list) {
+ db = list_entry(l, struct net_ns_dev, list);
+ dev = db-dev;
if (dev-type == type) {
dev_hold(dev);
- break;
+ goto out;
}
}
+ dev = NULL;
+out:
+ read_unlock(dev_list-lock);
rtnl_unlock();
return dev;
}
@@ -614,16 +643,23 @@
struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short
mask)
{
+ struct net_ns_dev_list *dev_list = (net_ns()-dev_list);
+ struct list_head *l, *list =