netns bridge: allow bridges in netns!
authorAlexey Dobriyan <adobriyan@gmail.com>
Mon, 8 Sep 2008 23:19:58 +0000 (16:19 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 8 Sep 2008 23:19:58 +0000 (16:19 -0700)
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 <adobriyan@gmail.com>
Acked-by: Stephen Hemminger <shemming@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/bridge/br_device.c
net/bridge/br_if.c
net/bridge/br_ioctl.c
net/bridge/br_netlink.c
net/bridge/br_notify.c
net/bridge/br_private.h
net/bridge/br_stp_bpdu.c

index 4f52c3d..22ba863 100644 (file)
@@ -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;
 }
index 63c18aa..66c4f71 100644 (file)
@@ -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 */
 
index eeee218..3ec1c63 100644 (file)
 #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 -EOPNOTSUPP;
Simple merge
Simple merge
Simple merge
Simple merge