[Devel] [PATCH 1/2] netns bridge: allow bridges in netns!

2008-09-08 Thread Alexey Dobriyan
Bridge as netdevice doesn't cross netns boundaries.

Bridge ports and bridge itself live in same netns.

Notifiers are fixed.

netns propagated from userspace socket for setup and teardown.

Signed-off-by: Alexey Dobriyan [EMAIL PROTECTED]
---

 net/bridge/br_device.c   |3 ++-
 net/bridge/br_if.c   |   11 ++-
 net/bridge/br_ioctl.c|   20 ++--
 net/bridge/br_netlink.c  |   15 +--
 net/bridge/br_notify.c   |3 ---
 net/bridge/br_private.h  |4 ++--
 net/bridge/br_stp_bpdu.c |3 ---
 7 files changed, 25 insertions(+), 34 deletions(-)

--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -178,5 +178,6 @@ void br_dev_setup(struct net_device *dev)
dev-priv_flags = IFF_EBRIDGE;
 
dev-features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
-   NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX;
+   NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX |
+   NETIF_F_NETNS_LOCAL;
 }
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -168,7 +168,7 @@ static void del_br(struct net_bridge *br)
unregister_netdevice(br-dev);
 }
 
-static struct net_device *new_bridge_dev(const char *name)
+static struct net_device *new_bridge_dev(struct net *net, const char *name)
 {
struct net_bridge *br;
struct net_device *dev;
@@ -178,6 +178,7 @@ static struct net_device *new_bridge_dev(const char *name)
 
if (!dev)
return NULL;
+   dev_net_set(dev, net);
 
br = netdev_priv(dev);
br-dev = dev;
@@ -262,12 +263,12 @@ static struct net_bridge_port *new_nbp(struct net_bridge 
*br,
return p;
 }
 
-int br_add_bridge(const char *name)
+int br_add_bridge(struct net *net, const char *name)
 {
struct net_device *dev;
int ret;
 
-   dev = new_bridge_dev(name);
+   dev = new_bridge_dev(net, name);
if (!dev)
return -ENOMEM;
 
@@ -294,13 +295,13 @@ out_free:
goto out;
 }
 
-int br_del_bridge(const char *name)
+int br_del_bridge(struct net *net, const char *name)
 {
struct net_device *dev;
int ret = 0;
 
rtnl_lock();
-   dev = __dev_get_by_name(init_net, name);
+   dev = __dev_get_by_name(net, name);
if (dev == NULL)
ret =  -ENXIO;  /* Could not find device */
 
--- a/net/bridge/br_ioctl.c
+++ b/net/bridge/br_ioctl.c
@@ -21,12 +21,12 @@
 #include br_private.h
 
 /* called with RTNL */
-static int get_bridge_ifindices(int *indices, int num)
+static int get_bridge_ifindices(struct net *net, int *indices, int num)
 {
struct net_device *dev;
int i = 0;
 
-   for_each_netdev(init_net, dev) {
+   for_each_netdev(net, dev) {
if (i = num)
break;
if (dev-priv_flags  IFF_EBRIDGE)
@@ -89,7 +89,7 @@ static int add_del_if(struct net_bridge *br, int ifindex, int 
isadd)
if (!capable(CAP_NET_ADMIN))
return -EPERM;
 
-   dev = dev_get_by_index(init_net, ifindex);
+   dev = dev_get_by_index(dev_net(br-dev), ifindex);
if (dev == NULL)
return -EINVAL;
 
@@ -309,7 +309,7 @@ static int old_dev_ioctl(struct net_device *dev, struct 
ifreq *rq, int cmd)
return -EOPNOTSUPP;
 }
 
-static int old_deviceless(void __user *uarg)
+static int old_deviceless(struct net *net, void __user *uarg)
 {
unsigned long args[3];
 
@@ -331,7 +331,7 @@ static int old_deviceless(void __user *uarg)
if (indices == NULL)
return -ENOMEM;
 
-   args[2] = get_bridge_ifindices(indices, args[2]);
+   args[2] = get_bridge_ifindices(net, indices, args[2]);
 
ret = copy_to_user((void __user *)args[1], indices, 
args[2]*sizeof(int))
? -EFAULT : args[2];
@@ -354,9 +354,9 @@ static int old_deviceless(void __user *uarg)
buf[IFNAMSIZ-1] = 0;
 
if (args[0] == BRCTL_ADD_BRIDGE)
-   return br_add_bridge(buf);
+   return br_add_bridge(net, buf);
 
-   return br_del_bridge(buf);
+   return br_del_bridge(net, buf);
}
}
 
@@ -368,7 +368,7 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int 
cmd, void __user *uar
switch (cmd) {
case SIOCGIFBR:
case SIOCSIFBR:
-   return old_deviceless(uarg);
+   return old_deviceless(net, uarg);
 
case SIOCBRADDBR:
case SIOCBRDELBR:
@@ -383,9 +383,9 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int 
cmd, void __user *uar
 
buf[IFNAMSIZ-1] = 0;
if (cmd == SIOCBRADDBR)
-   return br_add_bridge(buf);
+   return br_add_bridge(net, buf);
 
-   return br_del_bridge(buf);
+   return br_del_bridge(net, buf);
}
}

[Devel] [PATCH 1/2] netns bridge: allow bridges in netns!

2008-08-21 Thread adobriyan
Bridge as netdevice doesn't cross netns boundaries.

Bridge ports and bridge itself live in same netns.

Notifiers are fixed.

netns propagated from userspace socket.

Signed-off-by: Alexey Dobriyan [EMAIL PROTECTED]
---

 net/bridge/br_device.c   |3 ++-
 net/bridge/br_if.c   |   11 ++-
 net/bridge/br_ioctl.c|   20 ++--
 net/bridge/br_netlink.c  |   15 +--
 net/bridge/br_notify.c   |3 ---
 net/bridge/br_private.h  |4 ++--
 net/bridge/br_stp_bpdu.c |3 ---
 7 files changed, 25 insertions(+), 34 deletions(-)

--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -178,5 +178,6 @@ void br_dev_setup(struct net_device *dev)
dev-priv_flags = IFF_EBRIDGE;
 
dev-features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
-   NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX;
+   NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX |
+   NETIF_F_NETNS_LOCAL;
 }
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -168,7 +168,7 @@ static void del_br(struct net_bridge *br)
unregister_netdevice(br-dev);
 }
 
-static struct net_device *new_bridge_dev(const char *name)
+static struct net_device *new_bridge_dev(struct net *net, const char *name)
 {
struct net_bridge *br;
struct net_device *dev;
@@ -178,6 +178,7 @@ static struct net_device *new_bridge_dev(const char *name)
 
if (!dev)
return NULL;
+   dev_net_set(dev, net);
 
br = netdev_priv(dev);
br-dev = dev;
@@ -262,12 +263,12 @@ static struct net_bridge_port *new_nbp(struct net_bridge 
*br,
return p;
 }
 
-int br_add_bridge(const char *name)
+int br_add_bridge(struct net *net, const char *name)
 {
struct net_device *dev;
int ret;
 
-   dev = new_bridge_dev(name);
+   dev = new_bridge_dev(net, name);
if (!dev)
return -ENOMEM;
 
@@ -294,13 +295,13 @@ out_free:
goto out;
 }
 
-int br_del_bridge(const char *name)
+int br_del_bridge(struct net *net, const char *name)
 {
struct net_device *dev;
int ret = 0;
 
rtnl_lock();
-   dev = __dev_get_by_name(init_net, name);
+   dev = __dev_get_by_name(net, name);
if (dev == NULL)
ret =  -ENXIO;  /* Could not find device */
 
--- a/net/bridge/br_ioctl.c
+++ b/net/bridge/br_ioctl.c
@@ -21,12 +21,12 @@
 #include br_private.h
 
 /* called with RTNL */
-static int get_bridge_ifindices(int *indices, int num)
+static int get_bridge_ifindices(struct net *net, int *indices, int num)
 {
struct net_device *dev;
int i = 0;
 
-   for_each_netdev(init_net, dev) {
+   for_each_netdev(net, dev) {
if (i = num)
break;
if (dev-priv_flags  IFF_EBRIDGE)
@@ -89,7 +89,7 @@ static int add_del_if(struct net_bridge *br, int ifindex, int 
isadd)
if (!capable(CAP_NET_ADMIN))
return -EPERM;
 
-   dev = dev_get_by_index(init_net, ifindex);
+   dev = dev_get_by_index(dev_net(br-dev), ifindex);
if (dev == NULL)
return -EINVAL;
 
@@ -309,7 +309,7 @@ static int old_dev_ioctl(struct net_device *dev, struct 
ifreq *rq, int cmd)
return -EOPNOTSUPP;
 }
 
-static int old_deviceless(void __user *uarg)
+static int old_deviceless(struct net *net, void __user *uarg)
 {
unsigned long args[3];
 
@@ -331,7 +331,7 @@ static int old_deviceless(void __user *uarg)
if (indices == NULL)
return -ENOMEM;
 
-   args[2] = get_bridge_ifindices(indices, args[2]);
+   args[2] = get_bridge_ifindices(net, indices, args[2]);
 
ret = copy_to_user((void __user *)args[1], indices, 
args[2]*sizeof(int))
? -EFAULT : args[2];
@@ -354,9 +354,9 @@ static int old_deviceless(void __user *uarg)
buf[IFNAMSIZ-1] = 0;
 
if (args[0] == BRCTL_ADD_BRIDGE)
-   return br_add_bridge(buf);
+   return br_add_bridge(net, buf);
 
-   return br_del_bridge(buf);
+   return br_del_bridge(net, buf);
}
}
 
@@ -368,7 +368,7 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int 
cmd, void __user *uar
switch (cmd) {
case SIOCGIFBR:
case SIOCSIFBR:
-   return old_deviceless(uarg);
+   return old_deviceless(net, uarg);
 
case SIOCBRADDBR:
case SIOCBRDELBR:
@@ -383,9 +383,9 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int 
cmd, void __user *uar
 
buf[IFNAMSIZ-1] = 0;
if (cmd == SIOCBRADDBR)
-   return br_add_bridge(buf);
+   return br_add_bridge(net, buf);
 
-   return br_del_bridge(buf);
+   return br_del_bridge(net, buf);
}
}
return