* @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
  *
  * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
- *
- * @switchdev_port_obj_add: Add an object to port (see switchdev_obj_*).
- *
- * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj_*).
  */
 struct switchdev_ops {
        int     (*switchdev_port_attr_get)(struct net_device *dev,
        int     (*switchdev_port_attr_set)(struct net_device *dev,
                                           const struct switchdev_attr *attr,
                                           struct switchdev_trans *trans);
-       int     (*switchdev_port_obj_add)(struct net_device *dev,
-                                         const struct switchdev_obj *obj,
-                                         struct switchdev_trans *trans);
-       int     (*switchdev_port_obj_del)(struct net_device *dev,
-                                         const struct switchdev_obj *obj);
 };
 
 enum switchdev_notifier_type {
 
        return 0;
 }
 
-static int __switchdev_port_obj_add(struct net_device *dev,
-                                   const struct switchdev_obj *obj,
-                                   struct switchdev_trans *trans)
+static int switchdev_port_obj_notify(enum switchdev_notifier_type nt,
+                                    struct net_device *dev,
+                                    const struct switchdev_obj *obj,
+                                    struct switchdev_trans *trans)
 {
-       const struct switchdev_ops *ops = dev->switchdev_ops;
-       struct net_device *lower_dev;
-       struct list_head *iter;
-       int err = -EOPNOTSUPP;
-
-       if (ops && ops->switchdev_port_obj_add)
-               return ops->switchdev_port_obj_add(dev, obj, trans);
+       int rc;
+       int err;
 
-       /* Switch device port(s) may be stacked under
-        * bond/team/vlan dev, so recurse down to add object on
-        * each port.
-        */
+       struct switchdev_notifier_port_obj_info obj_info = {
+               .obj = obj,
+               .trans = trans,
+               .handled = false,
+       };
 
-       netdev_for_each_lower_dev(dev, lower_dev, iter) {
-               err = __switchdev_port_obj_add(lower_dev, obj, trans);
-               if (err)
-                       break;
+       rc = call_switchdev_blocking_notifiers(nt, dev, &obj_info.info);
+       err = notifier_to_errno(rc);
+       if (err) {
+               WARN_ON(!obj_info.handled);
+               return err;
        }
-
-       return err;
+       if (!obj_info.handled)
+               return -EOPNOTSUPP;
+       return 0;
 }
 
 static int switchdev_port_obj_add_now(struct net_device *dev,
         */
 
        trans.ph_prepare = true;
-       err = __switchdev_port_obj_add(dev, obj, &trans);
+       err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD,
+                                       dev, obj, &trans);
        if (err) {
                /* Prepare phase failed: abort the transaction.  Any
                 * resources reserved in the prepare phase are
         */
 
        trans.ph_prepare = false;
-       err = __switchdev_port_obj_add(dev, obj, &trans);
+       err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD,
+                                       dev, obj, &trans);
        WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id);
        switchdev_trans_items_warn_destroy(dev, &trans);
 
 static int switchdev_port_obj_del_now(struct net_device *dev,
                                      const struct switchdev_obj *obj)
 {
-       const struct switchdev_ops *ops = dev->switchdev_ops;
-       struct net_device *lower_dev;
-       struct list_head *iter;
-       int err = -EOPNOTSUPP;
-
-       if (ops && ops->switchdev_port_obj_del)
-               return ops->switchdev_port_obj_del(dev, obj);
-
-       /* Switch device port(s) may be stacked under
-        * bond/team/vlan dev, so recurse down to delete object on
-        * each port.
-        */
-
-       netdev_for_each_lower_dev(dev, lower_dev, iter) {
-               err = switchdev_port_obj_del_now(lower_dev, obj);
-               if (err)
-                       break;
-       }
-
-       return err;
+       return switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_DEL,
+                                        dev, obj, NULL);
 }
 
 static void switchdev_port_obj_del_deferred(struct net_device *dev,