diff options
author | stephen hemminger <shemminger@vyatta.com> | 2011-04-04 14:03:33 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-04 17:22:29 -0700 |
commit | 14f98f258f1936e0dba77474bd7eda63f61a9826 (patch) | |
tree | b74a80e8736c937be34291fb432f15a3f6aff67c /net/bridge/br_ioctl.c | |
parent | bb900b27a2f49b37bc38c08e656ea13048fee13b (diff) | |
download | op-kernel-dev-14f98f258f1936e0dba77474bd7eda63f61a9826.zip op-kernel-dev-14f98f258f1936e0dba77474bd7eda63f61a9826.tar.gz |
bridge: range check STP parameters
Apply restrictions on STP parameters based 802.1D 1998 standard.
* Fixes missing locking in set path cost ioctl
* Uses common code for both ioctl and sysfs
This is based on an earlier patch Sasikanth V but with overhaul.
Note:
1. It does NOT enforce the restriction on the relationship max_age and
forward delay or hello time because in existing implementation these are
set as independant operations.
2. If STP is disabled, there is no restriction on forward delay
3. No restriction on holding time because users use Linux code to act
as hub or be sticky.
4. Although standard allow 0-255, Linux only allows 0-63 for port priority
because more bits are reserved for port number.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_ioctl.c')
-rw-r--r-- | net/bridge/br_ioctl.c | 40 |
1 files changed, 9 insertions, 31 deletions
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index cb43312..0459890 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -181,40 +181,19 @@ 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); - br->bridge_forward_delay = clock_t_to_jiffies(args[1]); - if (br_is_root_bridge(br)) - br->forward_delay = br->bridge_forward_delay; - spin_unlock_bh(&br->lock); - return 0; + return br_set_forward_delay(br, args[1]); 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 = t; - if (br_is_root_bridge(br)) - br->hello_time = br->bridge_hello_time; - spin_unlock_bh(&br->lock); - return 0; - } + return br_set_hello_time(br, args[1]); case BRCTL_SET_BRIDGE_MAX_AGE: if (!capable(CAP_NET_ADMIN)) return -EPERM; - spin_lock_bh(&br->lock); - br->bridge_max_age = clock_t_to_jiffies(args[1]); - if (br_is_root_bridge(br)) - br->max_age = br->bridge_max_age; - spin_unlock_bh(&br->lock); - return 0; + return br_set_max_age(br, args[1]); case BRCTL_SET_AGEING_TIME: if (!capable(CAP_NET_ADMIN)) @@ -275,19 +254,16 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case BRCTL_SET_PORT_PRIORITY: { struct net_bridge_port *p; - int ret = 0; + int ret; if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (args[2] >= (1<<(16-BR_PORT_BITS))) - return -ERANGE; - spin_lock_bh(&br->lock); if ((p = br_get_port(br, args[1])) == NULL) ret = -EINVAL; else - br_stp_set_port_priority(p, args[2]); + ret = br_stp_set_port_priority(p, args[2]); spin_unlock_bh(&br->lock); return ret; } @@ -295,15 +271,17 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case BRCTL_SET_PATH_COST: { struct net_bridge_port *p; - int ret = 0; + int ret; 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]); + ret = br_stp_set_path_cost(p, args[2]); + spin_unlock_bh(&br->lock); return ret; } |