Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Michal Kubecek and committed by
David S. Miller
9c6451ef 0980bfcd

+39 -1
+6
Documentation/networking/ethtool-netlink.rst
··· 208 208 ``ETHTOOL_MSG_WOL_NTF`` wake-on-lan settings notification 209 209 ``ETHTOOL_MSG_FEATURES_GET_REPLY`` device features 210 210 ``ETHTOOL_MSG_FEATURES_SET_REPLY`` optional reply to FEATURES_SET 211 + ``ETHTOOL_MSG_FEATURES_NTF`` netdev features notification 211 212 ===================================== ================================= 212 213 213 214 ``GET`` requests are sent by userspace applications to retrieve device ··· 591 590 reports the difference between old and new dev->features: mask consists of 592 591 bits which have changed, values are their values in new dev->features (after 593 592 the operation). 593 + 594 + ``ETHTOOL_MSG_FEATURES_NTF`` notification is sent not only if device features 595 + are modified using ``ETHTOOL_MSG_FEATURES_SET`` request or on of ethtool ioctl 596 + request but also each time features are modified with netdev_update_features() 597 + or netdev_change_features(). 594 598 595 599 596 600 Request translation
+1
include/uapi/linux/ethtool_netlink.h
··· 47 47 ETHTOOL_MSG_WOL_NTF, 48 48 ETHTOOL_MSG_FEATURES_GET_REPLY, 49 49 ETHTOOL_MSG_FEATURES_SET_REPLY, 50 + ETHTOOL_MSG_FEATURES_NTF, 50 51 51 52 /* add new constants above here */ 52 53 __ETHTOOL_MSG_KERNEL_CNT,
+4
net/ethtool/features.c
··· 230 230 struct nlattr *tb[ETHTOOL_A_FEATURES_MAX + 1]; 231 231 struct ethnl_req_info req_info = {}; 232 232 struct net_device *dev; 233 + bool mod; 233 234 int ret; 234 235 235 236 ret = nlmsg_parse(info->nlhdr, GENL_HDRLEN, tb, ··· 273 272 dev->wanted_features = ethnl_bitmap_to_features(req_wanted); 274 273 __netdev_update_features(dev); 275 274 ethnl_features_to_bitmap(new_active, dev->features); 275 + mod = !bitmap_equal(old_active, new_active, NETDEV_FEATURE_COUNT); 276 276 277 277 ret = 0; 278 278 if (!(req_info.flags & ETHTOOL_FLAG_OMIT_REPLY)) { ··· 294 292 wanted_diff_mask, new_active, 295 293 active_diff_mask, compact); 296 294 } 295 + if (mod) 296 + ethtool_notify(dev, ETHTOOL_MSG_FEATURES_NTF, NULL); 297 297 298 298 out_rtnl: 299 299 rtnl_unlock();
+28 -1
net/ethtool/netlink.c
··· 528 528 [ETHTOOL_MSG_LINKMODES_NTF] = &ethnl_linkmodes_request_ops, 529 529 [ETHTOOL_MSG_DEBUG_NTF] = &ethnl_debug_request_ops, 530 530 [ETHTOOL_MSG_WOL_NTF] = &ethnl_wol_request_ops, 531 + [ETHTOOL_MSG_FEATURES_NTF] = &ethnl_features_request_ops, 531 532 }; 532 533 533 534 /* default notification handler */ ··· 614 613 [ETHTOOL_MSG_LINKMODES_NTF] = ethnl_default_notify, 615 614 [ETHTOOL_MSG_DEBUG_NTF] = ethnl_default_notify, 616 615 [ETHTOOL_MSG_WOL_NTF] = ethnl_default_notify, 616 + [ETHTOOL_MSG_FEATURES_NTF] = ethnl_default_notify, 617 617 }; 618 618 619 619 void ethtool_notify(struct net_device *dev, unsigned int cmd, const void *data) ··· 631 629 cmd, netdev_name(dev)); 632 630 } 633 631 EXPORT_SYMBOL(ethtool_notify); 632 + 633 + static void ethnl_notify_features(struct netdev_notifier_info *info) 634 + { 635 + struct net_device *dev = netdev_notifier_info_to_dev(info); 636 + 637 + ethtool_notify(dev, ETHTOOL_MSG_FEATURES_NTF, NULL); 638 + } 639 + 640 + static int ethnl_netdev_event(struct notifier_block *this, unsigned long event, 641 + void *ptr) 642 + { 643 + switch (event) { 644 + case NETDEV_FEAT_CHANGE: 645 + ethnl_notify_features(ptr); 646 + break; 647 + } 648 + 649 + return NOTIFY_DONE; 650 + } 651 + 652 + static struct notifier_block ethnl_netdev_notifier = { 653 + .notifier_call = ethnl_netdev_event, 654 + }; 634 655 635 656 /* genetlink setup */ 636 657 ··· 761 736 return ret; 762 737 ethnl_ok = true; 763 738 764 - return 0; 739 + ret = register_netdevice_notifier(&ethnl_netdev_notifier); 740 + WARN(ret < 0, "ethtool: net device notifier registration failed"); 741 + return ret; 765 742 } 766 743 767 744 subsys_initcall(ethnl_init);