Get rid of the dsa_slave_switchdev_port_{attr_set,obj}_event functions
in favor of the switchdev_handle_port_{attr_set,obj_add,obj_del}
helpers which recurse into the lower devices of the target interface.

This has the benefit of being aware of the operations made on the
bridge device itself, where orig_dev is the bridge, and dev is the
slave. This can be used later to configure bridge-wide attributes on
the hardware switches.

Signed-off-by: Vivien Didelot <[email protected]>
---
 net/dsa/slave.c | 77 +++++++++++++++++++++----------------------------
 1 file changed, 33 insertions(+), 44 deletions(-)

diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index cb436a05c9a8..915dd43873f9 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -283,6 +283,9 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
        struct dsa_port *dp = dsa_slave_to_port(dev);
        int ret;
 
+       if (attr->orig_dev != dev)
+               return -EOPNOTSUPP;
+
        switch (attr->id) {
        case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
                ret = dsa_port_set_state(dp, attr->u.stp_state, trans);
@@ -311,11 +314,15 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
 
 static int dsa_slave_port_obj_add(struct net_device *dev,
                                  const struct switchdev_obj *obj,
-                                 struct switchdev_trans *trans)
+                                 struct switchdev_trans *trans,
+                                 struct netlink_ext_ack *extack)
 {
        struct dsa_port *dp = dsa_slave_to_port(dev);
        int err;
 
+       if (obj->orig_dev != dev)
+               return -EOPNOTSUPP;
+
        /* For the prepare phase, ensure the full set of changes is feasable in
         * one go in order to signal a failure properly. If an operation is not
         * supported, return -EOPNOTSUPP.
@@ -350,6 +357,9 @@ static int dsa_slave_port_obj_del(struct net_device *dev,
        struct dsa_port *dp = dsa_slave_to_port(dev);
        int err;
 
+       if (obj->orig_dev != dev)
+               return -EOPNOTSUPP;
+
        switch (obj->id) {
        case SWITCHDEV_OBJ_ID_PORT_MDB:
                err = dsa_port_mdb_del(dp, SWITCHDEV_OBJ_PORT_MDB(obj));
@@ -1479,19 +1489,6 @@ static int dsa_slave_netdevice_event(struct 
notifier_block *nb,
        return NOTIFY_DONE;
 }
 
-static int
-dsa_slave_switchdev_port_attr_set_event(struct net_device *netdev,
-               struct switchdev_notifier_port_attr_info *port_attr_info)
-{
-       int err;
-
-       err = dsa_slave_port_attr_set(netdev, port_attr_info->attr,
-                                     port_attr_info->trans);
-
-       port_attr_info->handled = true;
-       return notifier_from_errno(err);
-}
-
 struct dsa_switchdev_event_work {
        struct work_struct work;
        struct switchdev_notifier_fdb_info fdb_info;
@@ -1566,13 +1563,18 @@ static int dsa_slave_switchdev_event(struct 
notifier_block *unused,
 {
        struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
        struct dsa_switchdev_event_work *switchdev_work;
+       int err;
+
+       if (event == SWITCHDEV_PORT_ATTR_SET) {
+               err = switchdev_handle_port_attr_set(dev, ptr,
+                                                    dsa_slave_dev_check,
+                                                    dsa_slave_port_attr_set);
+               return notifier_from_errno(err);
+       }
 
        if (!dsa_slave_dev_check(dev))
                return NOTIFY_DONE;
 
-       if (event == SWITCHDEV_PORT_ATTR_SET)
-               return dsa_slave_switchdev_port_attr_set_event(dev, ptr);
-
        switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
        if (!switchdev_work)
                return NOTIFY_BAD;
@@ -1602,41 +1604,28 @@ static int dsa_slave_switchdev_event(struct 
notifier_block *unused,
        return NOTIFY_BAD;
 }
 
-static int
-dsa_slave_switchdev_port_obj_event(unsigned long event,
-                       struct net_device *netdev,
-                       struct switchdev_notifier_port_obj_info *port_obj_info)
-{
-       int err = -EOPNOTSUPP;
-
-       switch (event) {
-       case SWITCHDEV_PORT_OBJ_ADD:
-               err = dsa_slave_port_obj_add(netdev, port_obj_info->obj,
-                                            port_obj_info->trans);
-               break;
-       case SWITCHDEV_PORT_OBJ_DEL:
-               err = dsa_slave_port_obj_del(netdev, port_obj_info->obj);
-               break;
-       }
-
-       port_obj_info->handled = true;
-       return notifier_from_errno(err);
-}
-
 static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
                                              unsigned long event, void *ptr)
 {
        struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
-
-       if (!dsa_slave_dev_check(dev))
-               return NOTIFY_DONE;
+       int err;
 
        switch (event) {
-       case SWITCHDEV_PORT_OBJ_ADD: /* fall through */
+       case SWITCHDEV_PORT_OBJ_ADD:
+               err = switchdev_handle_port_obj_add(dev, ptr,
+                                                   dsa_slave_dev_check,
+                                                   dsa_slave_port_obj_add);
+               return notifier_from_errno(err);
        case SWITCHDEV_PORT_OBJ_DEL:
-               return dsa_slave_switchdev_port_obj_event(event, dev, ptr);
+               err = switchdev_handle_port_obj_del(dev, ptr,
+                                                   dsa_slave_dev_check,
+                                                   dsa_slave_port_obj_del);
+               return notifier_from_errno(err);
        case SWITCHDEV_PORT_ATTR_SET:
-               return dsa_slave_switchdev_port_attr_set_event(dev, ptr);
+               err = switchdev_handle_port_attr_set(dev, ptr,
+                                                    dsa_slave_dev_check,
+                                                    dsa_slave_port_attr_set);
+               return notifier_from_errno(err);
        }
 
        return NOTIFY_DONE;
-- 
2.21.0

Reply via email to