Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp11053039ybl; Fri, 27 Dec 2019 06:57:36 -0800 (PST) X-Google-Smtp-Source: APXvYqzXgkeR9QCA44Dp5YNuHyW6+fV/QJZ72nF3klBicNdiQZJUJLPw8hxwa5d9XMU0xvTZqDJ1 X-Received: by 2002:a05:6830:16d1:: with SMTP id l17mr36293577otr.21.1577458655874; Fri, 27 Dec 2019 06:57:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1577458655; cv=none; d=google.com; s=arc-20160816; b=U3x1DWFUHQgiUgEosCo/2EDypLIuSypDRkNq/icKiG/k9w+cffkSHwbNS+a2l0tV7J 4ONGmOq/b0G9xmXwMCRjWHnlJaUMEixpVeXSJ7HmcFiMrfcy29WtGsMMLP5B4xUpHdoV AgfF4rN5ZXR5iMQYOHbgFMPhLqEvrmwyg+HuKdEN6P5qu98yupNDmjCJr7J+tWomVFbY c9zG6l3HfpW3u+GIVvn2RW5WM/PW2McecS1cNNb2n7OUnBYjf9djo0iWYKf1oDPQTR6N 1NwL4KdkALuyscvJKyMrlyXYKKC/sSVYMlYQUPPAhbftpfekFECvY9F1S8qseFpg8gDK vNIg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:date:cc:to:subject:from:references :in-reply-to:message-id; bh=09qd+Xjf9rB2qGF5Pd2WvaHQjTZpLsxm3ugmGOi2abg=; b=QixJVD/6S00CB1xrchUuHGK+MVYF4xMyAtopyXIaYFpvvclJYz3lnAzyVzQIE77EHO cZBdRQNrZ24OEnp+4D8lp5fUZIE7qk/w8mSJss4CRK5SJw/T6KHeQaQN0ODVikn/g2u8 Jc8sXFoZ6v5kdkH5UNlUUbC1OlOQSNulvdqGDdaVZvlAbwgnVi4zEVIBokMSbX13/Vx9 KjVpx9FWJdSddcpHpDi/LmPgEoQo2WpU6NJuPKWJ/NNskxDheZr5nJ1osZ+Mp+ccrWNT 36okzdTWfm2cjR3tvVmyhN83uB8Nu/hGO4/4Ur1d1lNF3ZS81pnJBJ1LVqguXVVn+J3N 9VZw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i205si16879404oih.257.2019.12.27.06.57.25; Fri, 27 Dec 2019 06:57:35 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727015AbfL0Ozk (ORCPT + 99 others); Fri, 27 Dec 2019 09:55:40 -0500 Received: from mx2.suse.de ([195.135.220.15]:42648 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726053AbfL0Ozf (ORCPT ); Fri, 27 Dec 2019 09:55:35 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 823E1AE57; Fri, 27 Dec 2019 14:55:33 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id 30D92E008A; Fri, 27 Dec 2019 15:55:33 +0100 (CET) Message-Id: <970a66c5f2579017e2952d82ac47079f7218563f.1577457846.git.mkubecek@suse.cz> In-Reply-To: References: From: Michal Kubecek Subject: [PATCH net-next v9 04/14] ethtool: support for netlink notifications To: David Miller , netdev@vger.kernel.org Cc: Jakub Kicinski , Jiri Pirko , Andrew Lunn , Florian Fainelli , John Linville , Stephen Hemminger , Johannes Berg , linux-kernel@vger.kernel.org Date: Fri, 27 Dec 2019 15:55:33 +0100 (CET) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add infrastructure for ethtool netlink notifications. There is only one multicast group "monitor" which is used to notify userspace about changes and actions performed. Notification messages (types using suffix _NTF) share the format with replies to GET requests. Notifications are supposed to be broadcasted on every configuration change, whether it is done using the netlink interface or ioctl one. Netlink SET requests only trigger a notification if some data is actually changed. To trigger an ethtool notification, both ethtool netlink and external code use ethtool_notify() helper. This helper requires RTNL to be held and may sleep. Handlers sending messages for specific notification message types are registered in ethnl_notify_handlers array. As notifications can be triggered from other code, ethnl_ok flag is used to prevent an attempt to send notification before genetlink family is registered. Signed-off-by: Michal Kubecek Reviewed-by: Florian Fainelli --- include/linux/ethtool_netlink.h | 5 +++++ include/linux/netdevice.h | 9 ++++++++ include/uapi/linux/ethtool_netlink.h | 2 ++ net/ethtool/netlink.c | 32 ++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+) diff --git a/include/linux/ethtool_netlink.h b/include/linux/ethtool_netlink.h index f27e92b5f344..c98f6852c8eb 100644 --- a/include/linux/ethtool_netlink.h +++ b/include/linux/ethtool_netlink.h @@ -5,5 +5,10 @@ #include #include +#include + +enum ethtool_multicast_groups { + ETHNL_MCGRP_MONITOR, +}; #endif /* _LINUX_ETHTOOL_NETLINK_H_ */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 469a297b58c0..f007155ae8f4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -4393,6 +4393,15 @@ struct netdev_notifier_bonding_info { void netdev_bonding_info_change(struct net_device *dev, struct netdev_bonding_info *bonding_info); +#if IS_ENABLED(CONFIG_ETHTOOL_NETLINK) +void ethtool_notify(struct net_device *dev, unsigned int cmd, const void *data); +#else +static inline void ethtool_notify(struct net_device *dev, unsigned int cmd, + const void *data) +{ +} +#endif + static inline struct sk_buff *skb_gso_segment(struct sk_buff *skb, netdev_features_t features) { diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h index 951203049615..d530ccb6f7e6 100644 --- a/include/uapi/linux/ethtool_netlink.h +++ b/include/uapi/linux/ethtool_netlink.h @@ -89,4 +89,6 @@ enum { #define ETHTOOL_GENL_NAME "ethtool" #define ETHTOOL_GENL_VERSION 1 +#define ETHTOOL_MCGRP_MONITOR_NAME "monitor" + #endif /* _UAPI_LINUX_ETHTOOL_NETLINK_H_ */ diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c index aef882e0c3f5..c0f25c8f3565 100644 --- a/net/ethtool/netlink.c +++ b/net/ethtool/netlink.c @@ -6,6 +6,8 @@ static struct genl_family ethtool_genl_family; +static bool ethnl_ok __read_mostly; + static const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_MAX + 1] = { [ETHTOOL_A_HEADER_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_HEADER_DEV_INDEX] = { .type = NLA_U32 }, @@ -169,11 +171,38 @@ struct sk_buff *ethnl_reply_init(size_t payload, struct net_device *dev, u8 cmd, return NULL; } +/* notifications */ + +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[] = { +}; + +void ethtool_notify(struct net_device *dev, unsigned int cmd, const void *data) +{ + if (unlikely(!ethnl_ok)) + return; + ASSERT_RTNL(); + + if (likely(cmd < ARRAY_SIZE(ethnl_notify_handlers) && + ethnl_notify_handlers[cmd])) + ethnl_notify_handlers[cmd](dev, cmd, data); + else + WARN_ONCE(1, "notification %u not implemented (dev=%s)\n", + cmd, netdev_name(dev)); +} +EXPORT_SYMBOL(ethtool_notify); + /* genetlink setup */ static const struct genl_ops ethtool_genl_ops[] = { }; +static const struct genl_multicast_group ethtool_nl_mcgrps[] = { + [ETHNL_MCGRP_MONITOR] = { .name = ETHTOOL_MCGRP_MONITOR_NAME }, +}; + static struct genl_family ethtool_genl_family = { .name = ETHTOOL_GENL_NAME, .version = ETHTOOL_GENL_VERSION, @@ -181,6 +210,8 @@ static struct genl_family ethtool_genl_family = { .parallel_ops = true, .ops = ethtool_genl_ops, .n_ops = ARRAY_SIZE(ethtool_genl_ops), + .mcgrps = ethtool_nl_mcgrps, + .n_mcgrps = ARRAY_SIZE(ethtool_nl_mcgrps), }; /* module setup */ @@ -192,6 +223,7 @@ static int __init ethnl_init(void) ret = genl_register_family(ðtool_genl_family); if (WARN(ret < 0, "ethtool: genetlink family registration failed")) return ret; + ethnl_ok = true; return 0; } -- 2.24.1