ethtool: add FEATURES_NTF notification
Send ETHTOOL_MSG_FEATURES_NTF notification whenever network device features are modified using ETHTOOL_MSG_FEATURES_SET netlink message, ethtool ioctl request or any other way resulting in call to netdev_update_features() or netdev_change_features() Signed-off-by: Michal Kubecek <mkubecek@suse.cz> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
0980bfcd69
commit
9c6451ef48
|
@ -208,6 +208,7 @@ Kernel to userspace:
|
|||
``ETHTOOL_MSG_WOL_NTF`` wake-on-lan settings notification
|
||||
``ETHTOOL_MSG_FEATURES_GET_REPLY`` device features
|
||||
``ETHTOOL_MSG_FEATURES_SET_REPLY`` optional reply to FEATURES_SET
|
||||
``ETHTOOL_MSG_FEATURES_NTF`` netdev features notification
|
||||
===================================== =================================
|
||||
|
||||
``GET`` requests are sent by userspace applications to retrieve device
|
||||
|
@ -591,6 +592,11 @@ reports the difference between old and new dev->features: mask consists of
|
|||
bits which have changed, values are their values in new dev->features (after
|
||||
the operation).
|
||||
|
||||
``ETHTOOL_MSG_FEATURES_NTF`` notification is sent not only if device features
|
||||
are modified using ``ETHTOOL_MSG_FEATURES_SET`` request or on of ethtool ioctl
|
||||
request but also each time features are modified with netdev_update_features()
|
||||
or netdev_change_features().
|
||||
|
||||
|
||||
Request translation
|
||||
===================
|
||||
|
|
|
@ -47,6 +47,7 @@ enum {
|
|||
ETHTOOL_MSG_WOL_NTF,
|
||||
ETHTOOL_MSG_FEATURES_GET_REPLY,
|
||||
ETHTOOL_MSG_FEATURES_SET_REPLY,
|
||||
ETHTOOL_MSG_FEATURES_NTF,
|
||||
|
||||
/* add new constants above here */
|
||||
__ETHTOOL_MSG_KERNEL_CNT,
|
||||
|
|
|
@ -230,6 +230,7 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
|
|||
struct nlattr *tb[ETHTOOL_A_FEATURES_MAX + 1];
|
||||
struct ethnl_req_info req_info = {};
|
||||
struct net_device *dev;
|
||||
bool mod;
|
||||
int ret;
|
||||
|
||||
ret = nlmsg_parse(info->nlhdr, GENL_HDRLEN, tb,
|
||||
|
@ -272,6 +273,7 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
|
|||
dev->wanted_features = ethnl_bitmap_to_features(req_wanted);
|
||||
__netdev_update_features(dev);
|
||||
ethnl_features_to_bitmap(new_active, dev->features);
|
||||
mod = !bitmap_equal(old_active, new_active, NETDEV_FEATURE_COUNT);
|
||||
|
||||
ret = 0;
|
||||
if (!(req_info.flags & ETHTOOL_FLAG_OMIT_REPLY)) {
|
||||
|
@ -292,6 +294,8 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
|
|||
wanted_diff_mask, new_active,
|
||||
active_diff_mask, compact);
|
||||
}
|
||||
if (mod)
|
||||
ethtool_notify(dev, ETHTOOL_MSG_FEATURES_NTF, NULL);
|
||||
|
||||
out_rtnl:
|
||||
rtnl_unlock();
|
||||
|
|
|
@ -528,6 +528,7 @@ ethnl_default_notify_ops[ETHTOOL_MSG_KERNEL_MAX + 1] = {
|
|||
[ETHTOOL_MSG_LINKMODES_NTF] = ðnl_linkmodes_request_ops,
|
||||
[ETHTOOL_MSG_DEBUG_NTF] = ðnl_debug_request_ops,
|
||||
[ETHTOOL_MSG_WOL_NTF] = ðnl_wol_request_ops,
|
||||
[ETHTOOL_MSG_FEATURES_NTF] = ðnl_features_request_ops,
|
||||
};
|
||||
|
||||
/* default notification handler */
|
||||
|
@ -613,6 +614,7 @@ static const ethnl_notify_handler_t ethnl_notify_handlers[] = {
|
|||
[ETHTOOL_MSG_LINKMODES_NTF] = ethnl_default_notify,
|
||||
[ETHTOOL_MSG_DEBUG_NTF] = ethnl_default_notify,
|
||||
[ETHTOOL_MSG_WOL_NTF] = ethnl_default_notify,
|
||||
[ETHTOOL_MSG_FEATURES_NTF] = ethnl_default_notify,
|
||||
};
|
||||
|
||||
void ethtool_notify(struct net_device *dev, unsigned int cmd, const void *data)
|
||||
|
@ -630,6 +632,29 @@ void ethtool_notify(struct net_device *dev, unsigned int cmd, const void *data)
|
|||
}
|
||||
EXPORT_SYMBOL(ethtool_notify);
|
||||
|
||||
static void ethnl_notify_features(struct netdev_notifier_info *info)
|
||||
{
|
||||
struct net_device *dev = netdev_notifier_info_to_dev(info);
|
||||
|
||||
ethtool_notify(dev, ETHTOOL_MSG_FEATURES_NTF, NULL);
|
||||
}
|
||||
|
||||
static int ethnl_netdev_event(struct notifier_block *this, unsigned long event,
|
||||
void *ptr)
|
||||
{
|
||||
switch (event) {
|
||||
case NETDEV_FEAT_CHANGE:
|
||||
ethnl_notify_features(ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block ethnl_netdev_notifier = {
|
||||
.notifier_call = ethnl_netdev_event,
|
||||
};
|
||||
|
||||
/* genetlink setup */
|
||||
|
||||
static const struct genl_ops ethtool_genl_ops[] = {
|
||||
|
@ -736,7 +761,9 @@ static int __init ethnl_init(void)
|
|||
return ret;
|
||||
ethnl_ok = true;
|
||||
|
||||
return 0;
|
||||
ret = register_netdevice_notifier(ðnl_netdev_notifier);
|
||||
WARN(ret < 0, "ethtool: net device notifier registration failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
subsys_initcall(ethnl_init);
|
||||
|
|
Loading…
Reference in New Issue
Block a user