Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp3257898ybi; Tue, 2 Jul 2019 04:51:14 -0700 (PDT) X-Google-Smtp-Source: APXvYqzxyNZ+sViKfjKhKaO1HiEySVUvzzVM3bMmZkbp07oKCwwUdt7rfIsaoAUeM52mwpd1e1sn X-Received: by 2002:a17:90a:32e4:: with SMTP id l91mr5272201pjb.17.1562068274221; Tue, 02 Jul 2019 04:51:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562068274; cv=none; d=google.com; s=arc-20160816; b=cy9ciSjjasnWjVJlC7P2jWog8pUFRpPwoxae6c6K/Jxlzk5yToGals8BCgJ1KMvtwD hvQjzFYCtlpWqct54fGDJRIKfe4er+yBedeui9hgnEYBMP4NMi9IH0uSCZLY2lk5Fkt6 6VrjaYAcECBF3g4Rgv3TYxAK4/HOgBPf9oiCFQiF2MykEnWR8Vxu/V3uwxKE5tvlzZwZ MNvBP9F38zBrTNOFohpftWOwFkCDZVcYWWG2UFHXQ2izJ5mCHjeOEAG1JOJlOgMZneMl alBwoh/masMy/ourFHOeM/wdvp1n8RiwaW0/qHeao6iz6ZgE4UNd98nSF8L73MGCoDKI wXjw== 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=eifXOwKYu2799YrUotq87htv6bfdvyrQdusLHeqNgOM=; b=DDDKWk+Nz0QfIznB7xA9r0/5nBxRg0OS4/XpCT8kDElryErozQ0gMUFnVh5bktzyfn DAWUn1yeLct/wv3fWU3XkV7f/teVpYhup6g8AOW3fGGsv+XhwaRKFf/gZB7GNj2voPt8 xoSDVBtbCrCxcwJkh9n8cxMfx1eVJkGHjsfyLO01n3P7Dhi5/Z5ASSTFlcHdYc21UadQ x32MOz/cqoI/xzyh3hjWHZ7AtxpEYBQDzcAkKYmASyEWzGm8TyxOqTkUrSapaPieZr1R s2R9KnPh5+TVdgG5MX8ZdV4qwdfm7FDrzJbMyGudpNp40L/7A45pmUBkjRsJaRnFOCuP odmA== 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 z7si13136914pgi.257.2019.07.02.04.50.59; Tue, 02 Jul 2019 04:51:14 -0700 (PDT) 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 S1727118AbfGBLuS (ORCPT + 99 others); Tue, 2 Jul 2019 07:50:18 -0400 Received: from mx2.suse.de ([195.135.220.15]:38700 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727059AbfGBLuQ (ORCPT ); Tue, 2 Jul 2019 07:50:16 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 929D0B14A; Tue, 2 Jul 2019 11:50:14 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id 413B1E0159; Tue, 2 Jul 2019 13:50:14 +0200 (CEST) Message-Id: <4dcac81783de8686edefa262a1db75f9e961b123.1562067622.git.mkubecek@suse.cz> In-Reply-To: References: From: Michal Kubecek Subject: [PATCH net-next v6 07/15] 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: Tue, 2 Jul 2019 13:50:14 +0200 (CEST) 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 --- include/linux/ethtool_netlink.h | 5 ++++ include/linux/netdevice.h | 12 ++++++++++ include/uapi/linux/ethtool_netlink.h | 2 ++ net/ethtool/netlink.c | 35 ++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/include/linux/ethtool_netlink.h b/include/linux/ethtool_netlink.h index 0412adb4f42f..2a15e64a16f3 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 88292953aa6f..c57d9917fd50 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -4350,6 +4350,18 @@ 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, struct netlink_ext_ack *extack, + unsigned int cmd, u32 req_mask, const void *data); +#else +static inline void ethtool_notify(struct net_device *dev, + struct netlink_ext_ack *extack, + unsigned int cmd, u32 req_mask, + 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 805f314f4454..8938a1f09057 100644 --- a/include/uapi/linux/ethtool_netlink.h +++ b/include/uapi/linux/ethtool_netlink.h @@ -91,4 +91,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 e13f29bbd625..a7a0bfe1818c 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 dflt_header_policy[ETHTOOL_A_HEADER_MAX + 1] = { [ETHTOOL_A_HEADER_UNSPEC] = { .type = NLA_REJECT }, [ETHTOOL_A_HEADER_DEV_INDEX] = { .type = NLA_U32 }, @@ -176,11 +178,41 @@ 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, + struct netlink_ext_ack *extack, + unsigned int cmd, u32 req_mask, + const void *data); + +static const ethnl_notify_handler_t ethnl_notify_handlers[] = { +}; + +void ethtool_notify(struct net_device *dev, struct netlink_ext_ack *extack, + unsigned int cmd, u32 req_mask, 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, extack, cmd, req_mask, data); + else + WARN_ONCE(1, "notification %u not implemented (dev=%s, req_mask=0x%x)\n", + cmd, netdev_name(dev), req_mask); +} +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, @@ -188,6 +220,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 */ @@ -199,6 +233,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.22.0