Three types of netlink notifications are introduced:
- ETHA_EVENT_NEWDEV to notify about newly registered network devices
- ETHA_EVENT_DELDEV to notify about unregistered network devices
- ETHA_EVENT_RENAMEDEV to notify about renamed network device
The notifications are triggered by NETDEV_REGISTER, NETDEV_UNREGISTER and
NETDEV_CHANGENAME notifiers.
These notifications are intended for applications and daemons monitoring
ethtool events to allow updating the list of existing devices without
having to open another socket for rtnetlink.
Signed-off-by: Michal Kubecek
---
Documentation/networking/ethtool-netlink.txt | 27
include/uapi/linux/ethtool_netlink.h | 37 +++
net/ethtool/netlink.c| 65
3 files changed, 129 insertions(+)
diff --git a/Documentation/networking/ethtool-netlink.txt
b/Documentation/networking/ethtool-netlink.txt
index 205ae4462e9e..b79c26b5e92b 100644
--- a/Documentation/networking/ethtool-netlink.txt
+++ b/Documentation/networking/ethtool-netlink.txt
@@ -125,6 +125,8 @@ which the request applies.
List of message types
-
+ETHNL_CMD_EVENTnotification only
+
All constants use ETHNL_CMD_ prefix, usually followed by "GET", "SET" or "ACT"
to indicate the type.
@@ -136,9 +138,34 @@ messages marked as "response only" in the table above.
"Get" messages with
NLM_F_DUMP flags and no device identification dump the information for all
devices supporting the request.
+Type ETHNL_CMD_EVENT is special, these messages are never used in userspace
+requests or kernel replies. They are only sent by kernel to sockets listening
+to "monitor" multicast group to inform userspace about certain events.
+
Later sections describe the format and semantics of these request messages.
+EVENT
+-
+
+EVENT messages are only used in kernel multicast notifications. Atributes
+correspond to specific event types, the same type can appear multiple times.
+
+ETHA_EVENT_NEWDEV (nested)new device was registered
+ ETHA_NEWDEV_DEV (nested)new device
+ETHA_EVENT_DELDEV (nested)device was unregistered
+ ETHA_DELDEV_DEV (nested)removed device
+ETHA_EVENT_RENAMEDEV (nested)device was renamed
+ ETHA_RENAMEDEV_DEV (nested)renamed device
+
+For ETHA_EVENT_RENAMEDEV, the name ETHA_RENAME_DEV/ETHA_DEV_NAME is the new
+name after the rename.
+
+Userspace application must expect multiple events to be present in one message
+and also multiple events of the same type (e.g. two or more newly registered
+devices).
+
+
Request translation
---
diff --git a/include/uapi/linux/ethtool_netlink.h
b/include/uapi/linux/ethtool_netlink.h
index b662d75a0636..7e192ad8ce3a 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -7,6 +7,7 @@
enum {
ETHNL_CMD_NOOP,
+ ETHNL_CMD_EVENT,/* only for notifications */
__ETHNL_CMD_CNT,
ETHNL_CMD_MAX = (__ETHNL_CMD_CNT - 1)
@@ -55,6 +56,42 @@ enum {
ETHA_BITSET_MAX = (__ETHA_BITSET_CNT - 1)
};
+/* events */
+
+enum {
+ ETHA_NEWDEV_UNSPEC,
+ ETHA_NEWDEV_DEV,/* nest - ETHA_DEV_* */
+
+ __ETHA_NEWDEV_CNT,
+ ETHA_NEWDEV_MAX = (__ETHA_NEWDEV_CNT - 1)
+};
+
+enum {
+ ETHA_DELDEV_UNSPEC,
+ ETHA_DELDEV_DEV,/* nest - ETHA_DEV_* */
+
+ __ETHA_DELDEV_CNT,
+ ETHA_DELDEV_MAX = (__ETHA_DELDEV_CNT - 1)
+};
+
+enum {
+ ETHA_RENAMEDEV_UNSPEC,
+ ETHA_RENAMEDEV_DEV, /* nest - ETHA_DEV_* */
+
+ __ETHA_RENAMEDEV_CNT,
+ ETHA_RENAMEDEV_MAX = (__ETHA_RENAMEDEV_CNT - 1)
+};
+
+enum {
+ ETHA_EVENT_UNSPEC,
+ ETHA_EVENT_NEWDEV, /* nest - ETHA_NEWDEV_* */
+ ETHA_EVENT_DELDEV, /* nest - ETHA_DELDEV_* */
+ ETHA_EVENT_RENAMEDEV, /* nest - ETHA_RENAMEDEV_* */
+
+ __ETHA_EVENT_CNT,
+ ETHA_EVENT_MAX = (__ETHA_EVENT_CNT - 1)
+};
+
/* generic netlink info */
#define ETHTOOL_GENL_NAME "ethtool"
#define ETHTOOL_GENL_VERSION 1
diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
index a5fa54c2b743..ee3424cd1f90 100644
--- a/net/ethtool/netlink.c
+++ b/net/ethtool/netlink.c
@@ -148,6 +148,67 @@ void ethtool_notify(struct net_device *dev, struct
netlink_ext_ack *extack,
}
EXPORT_SYMBOL(ethtool_notify);
+/* size of NEWDEV/DELDEV notification */
+static inline unsigned int dev_notify_size(void)
+{
+ return nla_total_size(dev_ident_size());
+}
+
+static void ethnl_notify_devlist(struct netdev_notifier_info *info,
+u16 ev_type, u16 dev_attr)
+{
+ struct net_device *dev = netdev_notifier_info_to_dev(info);
+ struct sk_buff *skb;
+ struct nlattr *nest;
+