mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-16 07:24:39 +08:00
Merge branch 'switchdev_ageing_time'
Scott Feldman says: ==================== switchdev: push bridge ageing_time attribute down Push bridge-level attributes down to switchdev drivers. This patchset adds the infrastructure and then pushes, as an example, ageing_time attribute down from bridge to switchdev (rocker) driver. Add some range-checking for ageing_time. RTNETLINK answers: Numerical result out of range Up until now, switchdev attrs where port-level attrs, so the netdev used in switchdev_attr_set() would be a switch port or bond of switch ports. With bridge-level attrs, the netdev passed to switchdev_attr_set() is the bridge netdev. The same recusive algo is used to visit the leaves of the stacked drivers to set the attr, it's just in this case we start one layer higher in the stack. One note is not all ports in the bridge may support setting a bridge-level attribute, so rather than failing the entire set, we'll skip over those ports returning -EOPNOTSUPP. v2->v3: Per Jiri review: push only ageing_time attr down at this time, and don't pass raw bridge IFLA_BR_* values; rather use new switchdev attr ID for ageing_time. v1->v2: rebase w/ net-next ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
d5404915a9
@ -4361,6 +4361,18 @@ static int rocker_port_brport_flags_set(struct rocker_port *rocker_port,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int rocker_port_bridge_ageing_time(struct rocker_port *rocker_port,
|
||||
struct switchdev_trans *trans,
|
||||
u32 ageing_time)
|
||||
{
|
||||
if (!switchdev_trans_ph_prepare(trans)) {
|
||||
rocker_port->ageing_time = clock_t_to_jiffies(ageing_time);
|
||||
mod_timer(&rocker_port->rocker->fdb_cleanup_timer, jiffies);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rocker_port_attr_set(struct net_device *dev,
|
||||
struct switchdev_attr *attr,
|
||||
struct switchdev_trans *trans)
|
||||
@ -4378,6 +4390,10 @@ static int rocker_port_attr_set(struct net_device *dev,
|
||||
err = rocker_port_brport_flags_set(rocker_port, trans,
|
||||
attr->u.brport_flags);
|
||||
break;
|
||||
case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
|
||||
err = rocker_port_bridge_ageing_time(rocker_port, trans,
|
||||
attr->u.ageing_time);
|
||||
break;
|
||||
default:
|
||||
err = -EOPNOTSUPP;
|
||||
break;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/list.h>
|
||||
|
||||
#define SWITCHDEV_F_NO_RECURSE BIT(0)
|
||||
#define SWITCHDEV_F_SKIP_EOPNOTSUPP BIT(1)
|
||||
|
||||
struct switchdev_trans_item {
|
||||
struct list_head list;
|
||||
@ -43,6 +44,7 @@ enum switchdev_attr_id {
|
||||
SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
|
||||
SWITCHDEV_ATTR_ID_PORT_STP_STATE,
|
||||
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
|
||||
SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
|
||||
};
|
||||
|
||||
struct switchdev_attr {
|
||||
@ -52,6 +54,7 @@ struct switchdev_attr {
|
||||
struct netdev_phys_item_id ppid; /* PORT_PARENT_ID */
|
||||
u8 stp_state; /* PORT_STP_STATE */
|
||||
unsigned long brport_flags; /* PORT_BRIDGE_FLAGS */
|
||||
u32 ageing_time; /* BRIDGE_AGEING_TIME */
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -200,8 +200,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||
if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
br->ageing_time = clock_t_to_jiffies(args[1]);
|
||||
return 0;
|
||||
return br_set_ageing_time(br, args[1]);
|
||||
|
||||
case BRCTL_GET_PORT_INFO:
|
||||
{
|
||||
|
@ -870,9 +870,9 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
|
||||
}
|
||||
|
||||
if (data[IFLA_BR_AGEING_TIME]) {
|
||||
u32 ageing_time = nla_get_u32(data[IFLA_BR_AGEING_TIME]);
|
||||
|
||||
br->ageing_time = clock_t_to_jiffies(ageing_time);
|
||||
err = br_set_ageing_time(br, nla_get_u32(data[IFLA_BR_AGEING_TIME]));
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (data[IFLA_BR_STP_STATE]) {
|
||||
|
@ -882,6 +882,7 @@ void __br_set_forward_delay(struct net_bridge *br, unsigned long t);
|
||||
int br_set_forward_delay(struct net_bridge *br, unsigned long x);
|
||||
int br_set_hello_time(struct net_bridge *br, unsigned long x);
|
||||
int br_set_max_age(struct net_bridge *br, unsigned long x);
|
||||
int br_set_ageing_time(struct net_bridge *br, u32 ageing_time);
|
||||
|
||||
|
||||
/* br_stp_if.c */
|
||||
|
@ -566,6 +566,29 @@ int br_set_max_age(struct net_bridge *br, unsigned long val)
|
||||
|
||||
}
|
||||
|
||||
int br_set_ageing_time(struct net_bridge *br, u32 ageing_time)
|
||||
{
|
||||
struct switchdev_attr attr = {
|
||||
.id = SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
|
||||
.flags = SWITCHDEV_F_SKIP_EOPNOTSUPP,
|
||||
.u.ageing_time = ageing_time,
|
||||
};
|
||||
unsigned long t = clock_t_to_jiffies(ageing_time);
|
||||
int err;
|
||||
|
||||
if (t < BR_MIN_AGEING_TIME || t > BR_MAX_AGEING_TIME)
|
||||
return -ERANGE;
|
||||
|
||||
err = switchdev_port_attr_set(br->dev, &attr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
br->ageing_time = t;
|
||||
mod_timer(&br->gc_timer, jiffies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __br_set_forward_delay(struct net_bridge *br, unsigned long t)
|
||||
{
|
||||
br->bridge_forward_delay = t;
|
||||
|
@ -102,8 +102,7 @@ static ssize_t ageing_time_show(struct device *d,
|
||||
|
||||
static int set_ageing_time(struct net_bridge *br, unsigned long val)
|
||||
{
|
||||
br->ageing_time = clock_t_to_jiffies(val);
|
||||
return 0;
|
||||
return br_set_ageing_time(br, val);
|
||||
}
|
||||
|
||||
static ssize_t ageing_time_store(struct device *d,
|
||||
|
@ -147,7 +147,7 @@ static int __switchdev_port_attr_set(struct net_device *dev,
|
||||
return ops->switchdev_port_attr_set(dev, attr, trans);
|
||||
|
||||
if (attr->flags & SWITCHDEV_F_NO_RECURSE)
|
||||
return err;
|
||||
goto done;
|
||||
|
||||
/* Switch device port(s) may be stacked under
|
||||
* bond/team/vlan dev, so recurse down to set attr on
|
||||
@ -156,10 +156,17 @@ static int __switchdev_port_attr_set(struct net_device *dev,
|
||||
|
||||
netdev_for_each_lower_dev(dev, lower_dev, iter) {
|
||||
err = __switchdev_port_attr_set(lower_dev, attr, trans);
|
||||
if (err == -EOPNOTSUPP &&
|
||||
attr->flags & SWITCHDEV_F_SKIP_EOPNOTSUPP)
|
||||
continue;
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
if (err == -EOPNOTSUPP && attr->flags & SWITCHDEV_F_SKIP_EOPNOTSUPP)
|
||||
err = 0;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user