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> Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
This commit is contained in:
parent
590baedcf7
commit
62e057b6df
|
@ -208,6 +208,7 @@ Kernel to userspace:
|
||||||
``ETHTOOL_MSG_WOL_NTF`` wake-on-lan settings notification
|
``ETHTOOL_MSG_WOL_NTF`` wake-on-lan settings notification
|
||||||
``ETHTOOL_MSG_FEATURES_GET_REPLY`` device features
|
``ETHTOOL_MSG_FEATURES_GET_REPLY`` device features
|
||||||
``ETHTOOL_MSG_FEATURES_SET_REPLY`` optional reply to FEATURES_SET
|
``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
|
``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
|
bits which have changed, values are their values in new dev->features (after
|
||||||
the operation).
|
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
|
Request translation
|
||||||
===================
|
===================
|
||||||
|
|
|
@ -47,6 +47,7 @@ enum {
|
||||||
ETHTOOL_MSG_WOL_NTF,
|
ETHTOOL_MSG_WOL_NTF,
|
||||||
ETHTOOL_MSG_FEATURES_GET_REPLY,
|
ETHTOOL_MSG_FEATURES_GET_REPLY,
|
||||||
ETHTOOL_MSG_FEATURES_SET_REPLY,
|
ETHTOOL_MSG_FEATURES_SET_REPLY,
|
||||||
|
ETHTOOL_MSG_FEATURES_NTF,
|
||||||
|
|
||||||
/* add new constants above here */
|
/* add new constants above here */
|
||||||
__ETHTOOL_MSG_KERNEL_CNT,
|
__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 nlattr *tb[ETHTOOL_A_FEATURES_MAX + 1];
|
||||||
struct ethnl_req_info req_info = {};
|
struct ethnl_req_info req_info = {};
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
bool mod;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = nlmsg_parse(info->nlhdr, GENL_HDRLEN, tb,
|
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);
|
dev->wanted_features = ethnl_bitmap_to_features(req_wanted);
|
||||||
__netdev_update_features(dev);
|
__netdev_update_features(dev);
|
||||||
ethnl_features_to_bitmap(new_active, dev->features);
|
ethnl_features_to_bitmap(new_active, dev->features);
|
||||||
|
mod = !bitmap_equal(old_active, new_active, NETDEV_FEATURE_COUNT);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if (!(req_info.flags & ETHTOOL_FLAG_OMIT_REPLY)) {
|
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,
|
wanted_diff_mask, new_active,
|
||||||
active_diff_mask, compact);
|
active_diff_mask, compact);
|
||||||
}
|
}
|
||||||
|
if (mod)
|
||||||
|
ethtool_notify(dev, ETHTOOL_MSG_FEATURES_NTF, NULL);
|
||||||
|
|
||||||
out_rtnl:
|
out_rtnl:
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
|
|
|
@ -530,6 +530,7 @@ ethnl_default_notify_ops[ETHTOOL_MSG_KERNEL_MAX + 1] = {
|
||||||
[ETHTOOL_MSG_LINKMODES_NTF] = ðnl_linkmodes_request_ops,
|
[ETHTOOL_MSG_LINKMODES_NTF] = ðnl_linkmodes_request_ops,
|
||||||
[ETHTOOL_MSG_DEBUG_NTF] = ðnl_debug_request_ops,
|
[ETHTOOL_MSG_DEBUG_NTF] = ðnl_debug_request_ops,
|
||||||
[ETHTOOL_MSG_WOL_NTF] = ðnl_wol_request_ops,
|
[ETHTOOL_MSG_WOL_NTF] = ðnl_wol_request_ops,
|
||||||
|
[ETHTOOL_MSG_FEATURES_NTF] = ðnl_features_request_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* default notification handler */
|
/* default notification handler */
|
||||||
|
@ -615,6 +616,7 @@ static const ethnl_notify_handler_t ethnl_notify_handlers[] = {
|
||||||
[ETHTOOL_MSG_LINKMODES_NTF] = ethnl_default_notify,
|
[ETHTOOL_MSG_LINKMODES_NTF] = ethnl_default_notify,
|
||||||
[ETHTOOL_MSG_DEBUG_NTF] = ethnl_default_notify,
|
[ETHTOOL_MSG_DEBUG_NTF] = ethnl_default_notify,
|
||||||
[ETHTOOL_MSG_WOL_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)
|
void ethtool_notify(struct net_device *dev, unsigned int cmd, const void *data)
|
||||||
|
@ -632,6 +634,29 @@ void ethtool_notify(struct net_device *dev, unsigned int cmd, const void *data)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ethtool_notify);
|
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 */
|
/* genetlink setup */
|
||||||
|
|
||||||
static const struct genl_ops ethtool_genl_ops[] = {
|
static const struct genl_ops ethtool_genl_ops[] = {
|
||||||
|
@ -738,7 +763,9 @@ static int __init ethnl_init(void)
|
||||||
return ret;
|
return ret;
|
||||||
ethnl_ok = true;
|
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);
|
subsys_initcall(ethnl_init);
|
||||||
|
|
Loading…
Reference in New Issue