Skip to content

Commit

Permalink
net: dsa: add support for bridge flags
Browse files Browse the repository at this point in the history
The Linux bridge implementation allows various properties of the bridge
to be controlled, such as flooding unknown unicast and multicast frames.
This patch adds the necessary DSA infrastructure to allow the Linux
bridge support to control these properties for DSA switches.

Reviewed-by: Vivien Didelot <vivien.didelot@gmail.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
[florian: Add missing dp and ds variables declaration to fix build]
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Russell King authored and David S. Miller committed Feb 21, 2019
1 parent 08e7162 commit 5765279
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/net/dsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,8 @@ struct dsa_switch_ops {
void (*port_stp_state_set)(struct dsa_switch *ds, int port,
u8 state);
void (*port_fast_age)(struct dsa_switch *ds, int port);
int (*port_egress_floods)(struct dsa_switch *ds, int port,
bool unicast, bool multicast);

/*
* VLAN support
Expand Down
2 changes: 2 additions & 0 deletions net/dsa/dsa_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ int dsa_port_mdb_add(const struct dsa_port *dp,
struct switchdev_trans *trans);
int dsa_port_mdb_del(const struct dsa_port *dp,
const struct switchdev_obj_port_mdb *mdb);
int dsa_port_bridge_flags(const struct dsa_port *dp, unsigned long flags,
struct switchdev_trans *trans);
int dsa_port_vlan_add(struct dsa_port *dp,
const struct switchdev_obj_port_vlan *vlan,
struct switchdev_trans *trans);
Expand Down
17 changes: 17 additions & 0 deletions net/dsa/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,23 @@ int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock,
return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
}

int dsa_port_bridge_flags(const struct dsa_port *dp, unsigned long flags,
struct switchdev_trans *trans)
{
struct dsa_switch *ds = dp->ds;
int port = dp->index;
int err = 0;

if (switchdev_trans_ph_prepare(trans))
return 0;

if (ds->ops->port_egress_floods)
err = ds->ops->port_egress_floods(ds, port, flags & BR_FLOOD,
flags & BR_MCAST_FLOOD);

return err;
}

int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
u16 vid)
{
Expand Down
9 changes: 9 additions & 0 deletions net/dsa/slave.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,9 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
ret = dsa_port_ageing_time(dp, attr->u.ageing_time, trans);
break;
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
ret = dsa_port_bridge_flags(dp, attr->u.brport_flags, trans);
break;
default:
ret = -EOPNOTSUPP;
break;
Expand Down Expand Up @@ -381,9 +384,15 @@ static int dsa_slave_get_port_parent_id(struct net_device *dev,
static int dsa_slave_port_attr_get(struct net_device *dev,
struct switchdev_attr *attr)
{
struct dsa_port *dp = dsa_slave_to_port(dev);
struct dsa_switch *ds = dp->ds;

switch (attr->id) {
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
attr->u.brport_flags_support = 0;
if (ds->ops->port_egress_floods)
attr->u.brport_flags_support |= BR_FLOOD |
BR_MCAST_FLOOD;
break;
default:
return -EOPNOTSUPP;
Expand Down

0 comments on commit 5765279

Please sign in to comment.