Caller passing down the SKIP_EOPNOTSUPP switchdev flag expects that -EOPNOTSUPP cannot be returned. But in case of direct op call without recurtion, this may happen. So fix this by checking it always on the end of __switchdev_port_attr_set function.
Showing the changes to net/switchdev/switchdev.c (1 of 1 file). Show all
Unified · Split
| @@ -225,8 +225,10 @@ static int __switchdev_port_attr_set(struct net_device *dev, · 224 unmodified lines | ||
| 225 | 225 | struct list_head *iter; |
| 226 | 226 | int err = -EOPNOTSUPP; |
| 227 | 227 | |
| 228 | − if (ops && ops->switchdev_port_attr_set) | |
| 229 | − return ops->switchdev_port_attr_set(dev, attr, trans); | |
| 228 | + if (ops && ops->switchdev_port_attr_set) { | |
| 229 | + err = ops->switchdev_port_attr_set(dev, attr, trans); | |
| 230 | + goto done; | |
| 231 | + } | |
| 230 | 232 | |
| 231 | 233 | if (attr->flags & SWITCHDEV_F_NO_RECURSE) |
| 232 | 234 | goto done; |
| @@ -238,9 +240,6 @@ static int __switchdev_port_attr_set(struct net_device *dev, · 5 unmodified lines | ||
| 238 | 240 | |
| 239 | 241 | netdev_for_each_lower_dev(dev, lower_dev, iter) { |
| 240 | 242 | err = __switchdev_port_attr_set(lower_dev, attr, trans); |
| 241 | − if (err == -EOPNOTSUPP && | |
| 242 | − attr->flags & SWITCHDEV_F_SKIP_EOPNOTSUPP) | |
| 243 | − continue; | |
| 244 | 243 | if (err) |
| 245 | 244 | break; |
| 246 | 245 | } |