]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
ethtool: add LINKINFO_NTF notification
authorMichal Kubecek <mkubecek@suse.cz>
Fri, 27 Dec 2019 14:56:03 +0000 (15:56 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sat, 28 Dec 2019 00:40:02 +0000 (16:40 -0800)
Send ETHTOOL_MSG_LINKINFO_NTF notification message whenever device link
settings are modified using ETHTOOL_MSG_LINKINFO_SET netlink message or
ETHTOOL_SLINKSETTINGS or ETHTOOL_SSET ioctl commands.

The notification message has the same format as reply to LINKINFO_GET
request. ETHTOOL_MSG_LINKINFO_SET netlink request only triggers the
notification if there is a change but the ioctl command handlers do not
check if there is an actual change and trigger the notification whenever
the commands are executed.

As all work is done by ethnl_default_notify() handler and callback
functions introduced to handle LINKINFO_GET requests, all that remains is
adding entries for ETHTOOL_MSG_LINKINFO_NTF into ethnl_notify_handlers and
ethnl_default_notify_ops lookup tables and calls to ethtool_notify() where
needed.

Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/networking/ethtool-netlink.rst
include/uapi/linux/ethtool_netlink.h
net/ethtool/ioctl.c
net/ethtool/linkinfo.c
net/ethtool/netlink.c

index 39c4aba324c3bf2e676a5b30453db7ad7fda716d..34254482d29521d4384e9f28c17e957af5a041b4 100644 (file)
@@ -189,6 +189,7 @@ Kernel to userspace:
   ===================================== ================================
   ``ETHTOOL_MSG_STRSET_GET_REPLY``      string set contents
   ``ETHTOOL_MSG_LINKINFO_GET_REPLY``    link settings
+  ``ETHTOOL_MSG_LINKINFO_NTF``          link settings notification
   ===================================== ================================
 
 ``GET`` requests are sent by userspace applications to retrieve device
index 5b7806a5bef8e5b4a8e7fb1fac8139e166ef07f7..d530fa30de36177e29732185d8f59bc4fabf3f37 100644 (file)
@@ -28,6 +28,7 @@ enum {
        ETHTOOL_MSG_KERNEL_NONE,
        ETHTOOL_MSG_STRSET_GET_REPLY,
        ETHTOOL_MSG_LINKINFO_GET_REPLY,
+       ETHTOOL_MSG_LINKINFO_NTF,
 
        /* add new constants above here */
        __ETHTOOL_MSG_KERNEL_CNT,
index 8a0a13b478e0a9c70267c0f815e9b483846c4d7c..11a467294a332d9c3672ac9e64ca54e5de32a957 100644 (file)
@@ -26,6 +26,7 @@
 #include <net/devlink.h>
 #include <net/xdp_sock.h>
 #include <net/flow_offload.h>
+#include <linux/ethtool_netlink.h>
 
 #include "common.h"
 
@@ -571,7 +572,10 @@ static int ethtool_set_link_ksettings(struct net_device *dev,
            != link_ksettings.base.link_mode_masks_nwords)
                return -EINVAL;
 
-       return dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings);
+       err = dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings);
+       if (err >= 0)
+               ethtool_notify(dev, ETHTOOL_MSG_LINKINFO_NTF, NULL);
+       return err;
 }
 
 /* Query device for its ethtool_cmd settings.
@@ -620,6 +624,7 @@ static int ethtool_set_settings(struct net_device *dev, void __user *useraddr)
 {
        struct ethtool_link_ksettings link_ksettings;
        struct ethtool_cmd cmd;
+       int ret;
 
        ASSERT_RTNL();
 
@@ -632,7 +637,10 @@ static int ethtool_set_settings(struct net_device *dev, void __user *useraddr)
                return -EINVAL;
        link_ksettings.base.link_mode_masks_nwords =
                __ETHTOOL_LINK_MODE_MASK_NU32;
-       return dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings);
+       ret = dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings);
+       if (ret >= 0)
+               ethtool_notify(dev, ETHTOOL_MSG_LINKINFO_NTF, NULL);
+       return ret;
 }
 
 static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
index 8a5f68f92425fd7380c7df8f9007820c197035fc..5d16cb4e8693d0b70666639c41b63a718e2f62c8 100644 (file)
@@ -155,6 +155,8 @@ int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info)
        ret = dev->ethtool_ops->set_link_ksettings(dev, &ksettings);
        if (ret < 0)
                GENL_SET_ERR_MSG(info, "link settings update failed");
+       else
+               ethtool_notify(dev, ETHTOOL_MSG_LINKINFO_NTF, NULL);
 
 out_ops:
        ethnl_ops_complete(dev);
index 057b67f8ba8ca42d34aa327a3194336fde3ddcf6..942da4ebdfe9ed302ed51e4c4da8962784f6a4db 100644 (file)
@@ -509,6 +509,7 @@ static int ethnl_default_done(struct netlink_callback *cb)
 
 static const struct ethnl_request_ops *
 ethnl_default_notify_ops[ETHTOOL_MSG_KERNEL_MAX + 1] = {
+       [ETHTOOL_MSG_LINKINFO_NTF]      = &ethnl_linkinfo_request_ops,
 };
 
 /* default notification handler */
@@ -589,6 +590,7 @@ typedef void (*ethnl_notify_handler_t)(struct net_device *dev, unsigned int cmd,
                                       const void *data);
 
 static const ethnl_notify_handler_t ethnl_notify_handlers[] = {
+       [ETHTOOL_MSG_LINKINFO_NTF]      = ethnl_default_notify,
 };
 
 void ethtool_notify(struct net_device *dev, unsigned int cmd, const void *data)