diff options
author | Scott Feldman <sfeldma@gmail.com> | 2015-10-08 22:23:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-10-12 08:20:20 -0400 |
commit | c62987bbd8a1a1664f99e89e3959339350a6131e (patch) | |
tree | 3a7455b6ab6b25335c709662b078c2375b700900 /net/bridge | |
parent | 464314ea6c119ebc22ee78453e63814453c31611 (diff) |
bridge: push bridge setting ageing_time down to switchdev
Use SWITCHDEV_F_SKIP_EOPNOTSUPP to skip over ports in bridge that don't
support setting ageing_time (or setting bridge attrs in general).
If push fails, don't update ageing_time in bridge and return err to user.
If push succeeds, update ageing_time in bridge and run gc_timer now to
recalabrate when to run gc_timer next, based on new ageing_time.
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br_ioctl.c | 3 | ||||
-rw-r--r-- | net/bridge/br_netlink.c | 6 | ||||
-rw-r--r-- | net/bridge/br_private.h | 1 | ||||
-rw-r--r-- | net/bridge/br_stp.c | 23 | ||||
-rw-r--r-- | net/bridge/br_sysfs_br.c | 3 |
5 files changed, 29 insertions, 7 deletions
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index 8d423bc649b9..263b4de4de57 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c | |||
@@ -200,8 +200,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
200 | if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) | 200 | if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) |
201 | return -EPERM; | 201 | return -EPERM; |
202 | 202 | ||
203 | br->ageing_time = clock_t_to_jiffies(args[1]); | 203 | return br_set_ageing_time(br, args[1]); |
204 | return 0; | ||
205 | 204 | ||
206 | case BRCTL_GET_PORT_INFO: | 205 | case BRCTL_GET_PORT_INFO: |
207 | { | 206 | { |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index d78b4429505a..544ab966d477 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -870,9 +870,9 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[], | |||
870 | } | 870 | } |
871 | 871 | ||
872 | if (data[IFLA_BR_AGEING_TIME]) { | 872 | if (data[IFLA_BR_AGEING_TIME]) { |
873 | u32 ageing_time = nla_get_u32(data[IFLA_BR_AGEING_TIME]); | 873 | err = br_set_ageing_time(br, nla_get_u32(data[IFLA_BR_AGEING_TIME])); |
874 | 874 | if (err) | |
875 | br->ageing_time = clock_t_to_jiffies(ageing_time); | 875 | return err; |
876 | } | 876 | } |
877 | 877 | ||
878 | if (data[IFLA_BR_STP_STATE]) { | 878 | if (data[IFLA_BR_STP_STATE]) { |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 09d3ecbcb4f0..ba0c67b2159a 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -882,6 +882,7 @@ void __br_set_forward_delay(struct net_bridge *br, unsigned long t); | |||
882 | int br_set_forward_delay(struct net_bridge *br, unsigned long x); | 882 | int br_set_forward_delay(struct net_bridge *br, unsigned long x); |
883 | int br_set_hello_time(struct net_bridge *br, unsigned long x); | 883 | int br_set_hello_time(struct net_bridge *br, unsigned long x); |
884 | int br_set_max_age(struct net_bridge *br, unsigned long x); | 884 | int br_set_max_age(struct net_bridge *br, unsigned long x); |
885 | int br_set_ageing_time(struct net_bridge *br, u32 ageing_time); | ||
885 | 886 | ||
886 | 887 | ||
887 | /* br_stp_if.c */ | 888 | /* br_stp_if.c */ |
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index 3a982c02599a..db6d243defb2 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c | |||
@@ -566,6 +566,29 @@ int br_set_max_age(struct net_bridge *br, unsigned long val) | |||
566 | 566 | ||
567 | } | 567 | } |
568 | 568 | ||
569 | int br_set_ageing_time(struct net_bridge *br, u32 ageing_time) | ||
570 | { | ||
571 | struct switchdev_attr attr = { | ||
572 | .id = SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME, | ||
573 | .flags = SWITCHDEV_F_SKIP_EOPNOTSUPP, | ||
574 | .u.ageing_time = ageing_time, | ||
575 | }; | ||
576 | unsigned long t = clock_t_to_jiffies(ageing_time); | ||
577 | int err; | ||
578 | |||
579 | if (t < BR_MIN_AGEING_TIME || t > BR_MAX_AGEING_TIME) | ||
580 | return -ERANGE; | ||
581 | |||
582 | err = switchdev_port_attr_set(br->dev, &attr); | ||
583 | if (err) | ||
584 | return err; | ||
585 | |||
586 | br->ageing_time = t; | ||
587 | mod_timer(&br->gc_timer, jiffies); | ||
588 | |||
589 | return 0; | ||
590 | } | ||
591 | |||
569 | void __br_set_forward_delay(struct net_bridge *br, unsigned long t) | 592 | void __br_set_forward_delay(struct net_bridge *br, unsigned long t) |
570 | { | 593 | { |
571 | br->bridge_forward_delay = t; | 594 | br->bridge_forward_delay = t; |
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c index 4c97fc50fb70..04ef1926ee7e 100644 --- a/net/bridge/br_sysfs_br.c +++ b/net/bridge/br_sysfs_br.c | |||
@@ -102,8 +102,7 @@ static ssize_t ageing_time_show(struct device *d, | |||
102 | 102 | ||
103 | static int set_ageing_time(struct net_bridge *br, unsigned long val) | 103 | static int set_ageing_time(struct net_bridge *br, unsigned long val) |
104 | { | 104 | { |
105 | br->ageing_time = clock_t_to_jiffies(val); | 105 | return br_set_ageing_time(br, val); |
106 | return 0; | ||
107 | } | 106 | } |
108 | 107 | ||
109 | static ssize_t ageing_time_store(struct device *d, | 108 | static ssize_t ageing_time_store(struct device *d, |