net: dsa: add support for bridge flags
authorRussell King <rmk+kernel@armlinux.org.uk>
Wed, 20 Feb 2019 23:35:04 +0000 (15:35 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 21 Feb 2019 22:53:07 +0000 (14:53 -0800)
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>
include/net/dsa.h
net/dsa/dsa_priv.h
net/dsa/port.c
net/dsa/slave.c

index 7f2a668ef2ccefda0b117575837f0fdc0260abbc..2c2c10812814e7d400f60c9c865b0f554195c278 100644 (file)
@@ -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
index 1f4972dab9f2f8fe6554ca1c82306db6cd65adf4..f4f99ec29f5da042af696c2a03377ef103b53982 100644 (file)
@@ -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);
index 2d7e01b23572877423aabd002e7e74315e320882..6df29bddf37e8a5c67a2d00870169deef92f578b 100644 (file)
@@ -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)
 {
index 2e5e7c04821bec6c620315a60493f74502a1d8f1..85dc68611002a0627730a8af4f959803d1749ee0 100644 (file)
@@ -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;
@@ -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;