Skip to content

Commit

Permalink
switchdev: Add SWITCHDEV_PORT_ATTR_SET
Browse files Browse the repository at this point in the history
In preparation for allowing switchdev enabled drivers to veto specific
attribute settings from within the context of the caller, introduce a
new switchdev notifier type for port attributes.

Suggested-by: Ido Schimmel <[email protected]>
Reviewed-by: Ido Schimmel <[email protected]>
Signed-off-by: Florian Fainelli <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
ffainelli authored and davem330 committed Feb 27, 2019
1 parent 1d99787 commit 1cb33af
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
27 changes: 27 additions & 0 deletions include/net/switchdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ enum switchdev_notifier_type {

SWITCHDEV_PORT_OBJ_ADD, /* Blocking. */
SWITCHDEV_PORT_OBJ_DEL, /* Blocking. */
SWITCHDEV_PORT_ATTR_SET, /* May be blocking . */

SWITCHDEV_VXLAN_FDB_ADD_TO_BRIDGE,
SWITCHDEV_VXLAN_FDB_DEL_TO_BRIDGE,
Expand Down Expand Up @@ -160,6 +161,13 @@ struct switchdev_notifier_port_obj_info {
bool handled;
};

struct switchdev_notifier_port_attr_info {
struct switchdev_notifier_info info; /* must be first */
const struct switchdev_attr *attr;
struct switchdev_trans *trans;
bool handled;
};

static inline struct net_device *
switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
{
Expand Down Expand Up @@ -212,7 +220,15 @@ int switchdev_handle_port_obj_del(struct net_device *dev,
int (*del_cb)(struct net_device *dev,
const struct switchdev_obj *obj));

int switchdev_handle_port_attr_set(struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info,
bool (*check_cb)(const struct net_device *dev),
int (*set_cb)(struct net_device *dev,
const struct switchdev_attr *attr,
struct switchdev_trans *trans));

#define SWITCHDEV_SET_OPS(netdev, ops) ((netdev)->switchdev_ops = (ops))

#else

static inline void switchdev_deferred_process(void)
Expand Down Expand Up @@ -299,6 +315,17 @@ switchdev_handle_port_obj_del(struct net_device *dev,
return 0;
}

static inline int
switchdev_handle_port_attr_set(struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info,
bool (*check_cb)(const struct net_device *dev),
int (*set_cb)(struct net_device *dev,
const struct switchdev_attr *attr,
struct switchdev_trans *trans))
{
return 0;
}

#define SWITCHDEV_SET_OPS(netdev, ops) do {} while (0)

#endif
Expand Down
51 changes: 51 additions & 0 deletions net/switchdev/switchdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,3 +655,54 @@ int switchdev_handle_port_obj_del(struct net_device *dev,
return err;
}
EXPORT_SYMBOL_GPL(switchdev_handle_port_obj_del);

static int __switchdev_handle_port_attr_set(struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info,
bool (*check_cb)(const struct net_device *dev),
int (*set_cb)(struct net_device *dev,
const struct switchdev_attr *attr,
struct switchdev_trans *trans))
{
struct net_device *lower_dev;
struct list_head *iter;
int err = -EOPNOTSUPP;

if (check_cb(dev)) {
port_attr_info->handled = true;
return set_cb(dev, port_attr_info->attr,
port_attr_info->trans);
}

/* Switch ports might be stacked under e.g. a LAG. Ignore the
* unsupported devices, another driver might be able to handle them. But
* propagate to the callers any hard errors.
*
* If the driver does its own bookkeeping of stacked ports, it's not
* necessary to go through this helper.
*/
netdev_for_each_lower_dev(dev, lower_dev, iter) {
err = __switchdev_handle_port_attr_set(lower_dev, port_attr_info,
check_cb, set_cb);
if (err && err != -EOPNOTSUPP)
return err;
}

return err;
}

int switchdev_handle_port_attr_set(struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info,
bool (*check_cb)(const struct net_device *dev),
int (*set_cb)(struct net_device *dev,
const struct switchdev_attr *attr,
struct switchdev_trans *trans))
{
int err;

err = __switchdev_handle_port_attr_set(dev, port_attr_info, check_cb,
set_cb);
if (err == -EOPNOTSUPP)
err = 0;
return err;
}
EXPORT_SYMBOL_GPL(switchdev_handle_port_attr_set);

0 comments on commit 1cb33af

Please sign in to comment.