netfilter: bridge: use NFPROTO values for NF_HOOK invocation
[safe/jmp/linux-2.6] / net / bridge / br_ioctl.c
index 3ab153d..2af6e4a 100644 (file)
@@ -5,8 +5,6 @@
  *     Authors:
  *     Lennert Buytenhek               <buytenh@gnu.org>
  *
- *     $Id: br_ioctl.c,v 1.4 2000/11/08 05:16:40 davem Exp $
- *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
  *     as published by the Free Software Foundation; either version
 #include <linux/if_bridge.h>
 #include <linux/netdevice.h>
 #include <linux/times.h>
+#include <net/net_namespace.h>
 #include <asm/uaccess.h>
 #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 (dev = dev_base; dev && i < num; dev = dev->next) {
+       for_each_netdev(net, dev) {
+               if (i >= num)
+                       break;
                if (dev->priv_flags & IFF_EBRIDGE)
                        indices[i++] = dev->ifindex;
        }
@@ -80,6 +81,7 @@ static int get_fdb_entries(struct net_bridge *br, void __user *userbuf,
        return num;
 }
 
+/* called with RTNL */
 static int add_del_if(struct net_bridge *br, int ifindex, int isadd)
 {
        struct net_device *dev;
@@ -88,7 +90,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(ifindex);
+       dev = __dev_get_by_index(dev_net(br->dev), ifindex);
        if (dev == NULL)
                return -EINVAL;
 
@@ -97,7 +99,6 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd)
        else
                ret = br_del_if(br, dev);
 
-       dev_put(dev);
        return ret;
 }
 
@@ -137,7 +138,8 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                b.topology_change = br->topology_change;
                b.topology_change_detected = br->topology_change_detected;
                b.root_port = br->root_port;
-               b.stp_enabled = br->stp_enabled;
+
+               b.stp_enabled = (br->stp_enabled != BR_NO_STP);
                b.ageing_time = jiffies_to_clock_t(br->ageing_time);
                b.hello_timer_value = br_timer_value(&br->hello_timer);
                b.tcn_timer_value = br_timer_value(&br->tcn_timer);
@@ -186,15 +188,21 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                return 0;
 
        case BRCTL_SET_BRIDGE_HELLO_TIME:
+       {
+               unsigned long t = clock_t_to_jiffies(args[1]);
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
 
+               if (t < HZ)
+                       return -EINVAL;
+
                spin_lock_bh(&br->lock);
-               br->bridge_hello_time = clock_t_to_jiffies(args[1]);
+               br->bridge_hello_time = t;
                if (br_is_root_bridge(br))
                        br->hello_time = br->bridge_hello_time;
                spin_unlock_bh(&br->lock);
                return 0;
+       }
 
        case BRCTL_SET_BRIDGE_MAX_AGE:
                if (!capable(CAP_NET_ADMIN))
@@ -251,7 +259,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
 
-               br->stp_enabled = args[1]?1:0;
+               br_stp_set_enabled(br, args[1]);
                return 0;
 
        case BRCTL_SET_BRIDGE_PRIORITY:
@@ -291,12 +299,11 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
 
-               spin_lock_bh(&br->lock);
                if ((p = br_get_port(br, args[1])) == NULL)
                        ret = -EINVAL;
                else
                        br_stp_set_path_cost(p, args[2]);
-               spin_unlock_bh(&br->lock);
+
                return ret;
        }
 
@@ -308,7 +315,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];
 
@@ -330,7 +337,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];
@@ -353,21 +360,21 @@ 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);
        }
        }
 
        return -EOPNOTSUPP;
 }
 
-int br_ioctl_deviceless_stub(unsigned int cmd, void __user *uarg)
+int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uarg)
 {
        switch (cmd) {
        case SIOCGIFBR:
        case SIOCSIFBR:
-               return old_deviceless(uarg);
+               return old_deviceless(net, uarg);
 
        case SIOCBRADDBR:
        case SIOCBRDELBR:
@@ -382,9 +389,9 @@ int br_ioctl_deviceless_stub(unsigned int cmd, void __user *uarg)
 
                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;