summaryrefslogtreecommitdiffstats
path: root/net/switchdev/switchdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/switchdev/switchdev.c')
-rw-r--r--net/switchdev/switchdev.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 362413c9b389..3560c19aa7e2 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -655,3 +655,54 @@ int switchdev_handle_port_obj_del(struct net_device *dev,
655 return err; 655 return err;
656} 656}
657EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_del); 657EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_del);
658
659static int __switchdev_handle_port_attr_set(struct net_device *dev,
660 struct switchdev_notifier_port_attr_info *port_attr_info,
661 bool (*check_cb)(const struct net_device *dev),
662 int (*set_cb)(struct net_device *dev,
663 const struct switchdev_attr *attr,
664 struct switchdev_trans *trans))
665{
666 struct net_device *lower_dev;
667 struct list_head *iter;
668 int err = -EOPNOTSUPP;
669
670 if (check_cb(dev)) {
671 port_attr_info->handled = true;
672 return set_cb(dev, port_attr_info->attr,
673 port_attr_info->trans);
674 }
675
676 /* Switch ports might be stacked under e.g. a LAG. Ignore the
677 * unsupported devices, another driver might be able to handle them. But
678 * propagate to the callers any hard errors.
679 *
680 * If the driver does its own bookkeeping of stacked ports, it's not
681 * necessary to go through this helper.
682 */
683 netdev_for_each_lower_dev(dev, lower_dev, iter) {
684 err = __switchdev_handle_port_attr_set(lower_dev, port_attr_info,
685 check_cb, set_cb);
686 if (err && err != -EOPNOTSUPP)
687 return err;
688 }
689
690 return err;
691}
692
693int switchdev_handle_port_attr_set(struct net_device *dev,
694 struct switchdev_notifier_port_attr_info *port_attr_info,
695 bool (*check_cb)(const struct net_device *dev),
696 int (*set_cb)(struct net_device *dev,
697 const struct switchdev_attr *attr,
698 struct switchdev_trans *trans))
699{
700 int err;
701
702 err = __switchdev_handle_port_attr_set(dev, port_attr_info, check_cb,
703 set_cb);
704 if (err == -EOPNOTSUPP)
705 err = 0;
706 return err;
707}
708EXPORT_SYMBOL_GPL(switchdev_handle_port_attr_set);