Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp3921139imm; Mon, 30 Jul 2018 05:55:56 -0700 (PDT) X-Google-Smtp-Source: AAOMgpdUWDh+0jd+7WIlun68Kv13KM2e0akTI2DPAi/y/wwyAiOVKXE0fdjm4h5tlQRZ6f0Sb5Xi X-Received: by 2002:a17:902:e18d:: with SMTP id cd13-v6mr15964064plb.305.1532955356912; Mon, 30 Jul 2018 05:55:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532955356; cv=none; d=google.com; s=arc-20160816; b=mU00N5aw6HwUhKQrkFh0QWM86KWRZGWJEgY8FaJcIRtAtS3+7AnS1Q9SyCQ5nMYhzk n0jTiu/Z9DDAFfUR8PFAMUlfMRoTHpldOEZZQgUP1Ikoi51IcyhJuBXK5ibjxIHV8avR xsbGArbF/IczOg9HVCF9raJIWn2DDxG0tCnAO5mnYqwYtgFQKOmyJ5LLhs81sTs03Ak6 tCB0ecdaRovQV5QmfvfOMUq2wnZSQ1DA4zDWIIf/F7WMdHHDU5nvErUxDM3emF9ePcy0 hTyrNaz0WLl3QcmFSO7MPtVn0f/dOe/2zrVMgh1R943KtG+S9p07VKR0DH6k4fV5iY9f Z9og== 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:arc-authentication-results; bh=rYHE8SUveS5y0B7902J/CeeztTDe3r6ZHmgaAbkB5xc=; b=mgmmGCOpJAwS3rmbU9Td3J/iirSxz+EGOd/90Lyp86c+0/2fdfZ72DeSVrsrffJ36C E2PbcKZR8J29SubMKiuMrPYs1kdPXh2F6P7mRLIkxgM2mdRFszrN+47QGUS+r54mCOT5 LgRz7jR+j9tGtDWuhi8FhIJZUNLYNDTJTxZT1mtvyIx7k085663/7O8d9oB8bQtQQOkL Cx7RepBdFUJxO3sTpf+DSJfC2MZn3yz0I8H9guJJmwvj6132D1p9Wtpy59E5V//b7laq XrKFfLZ4tvzP36iewh7RoUHySljzijkDO8eBT/aPXd3gxjFZe7EQwJUYiLzfsIK1FVPK 74yg== 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 92-v6si10202414pli.518.2018.07.30.05.55.42; Mon, 30 Jul 2018 05:55:56 -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 S1732239AbeG3O25 (ORCPT + 99 others); Mon, 30 Jul 2018 10:28:57 -0400 Received: from mx2.suse.de ([195.135.220.15]:49542 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1732219AbeG3O24 (ORCPT ); Mon, 30 Jul 2018 10:28:56 -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 171E7AE83; Mon, 30 Jul 2018 12:54:03 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id BCDB8A0BE8; Mon, 30 Jul 2018 14:54:02 +0200 (CEST) Message-Id: In-Reply-To: References: From: Michal Kubecek Subject: [RFC PATCH net-next v2 16/17] ethtool: implement SET_PARAMS notification To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Jiri Pirko , David Miller , Florian Fainelli , Roopa Prabhu , Jakub Kicinski , "John W. Linville" Date: Mon, 30 Jul 2018 14:54:02 +0200 (CEST) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org SET_PARAMS notification message has the same format as response to GET_PARAMS request and is broadcasted on change of relevant fields. Info mask can be used to limit the information passed to userspace. Also trigger the notification on analogous changes performed via the legacy ioctl interface. Signed-off-by: Michal Kubecek --- net/ethtool/ioctl.c | 42 ++++++++++++++++++++++++++++++++++++------ net/ethtool/netlink.c | 3 +++ net/ethtool/params.c | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index 2754d3f6fd75..1dc1459dff6e 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -1337,6 +1337,7 @@ static int ethtool_get_eee(struct net_device *dev, char __user *useraddr) static int ethtool_set_eee(struct net_device *dev, char __user *useraddr) { struct ethtool_eee edata; + int ret; if (!dev->ethtool_ops->set_eee) return -EOPNOTSUPP; @@ -1344,7 +1345,11 @@ static int ethtool_set_eee(struct net_device *dev, char __user *useraddr) if (copy_from_user(&edata, useraddr, sizeof(edata))) return -EFAULT; - return dev->ethtool_ops->set_eee(dev, &edata); + ret = dev->ethtool_ops->set_eee(dev, &edata); + if (ret >= 0) + netdev_ethtool_info_change(dev, NULL, ETHNL_CMD_SET_PARAMS, + ETH_PARAMS_IM_EEE); + return ret; } static int ethtool_nway_reset(struct net_device *dev) @@ -1499,6 +1504,7 @@ static noinline_for_stack int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr) { struct ethtool_coalesce coalesce; + int ret; if (!dev->ethtool_ops->set_coalesce) return -EOPNOTSUPP; @@ -1506,7 +1512,11 @@ static noinline_for_stack int ethtool_set_coalesce(struct net_device *dev, if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) return -EFAULT; - return dev->ethtool_ops->set_coalesce(dev, &coalesce); + ret = dev->ethtool_ops->set_coalesce(dev, &coalesce); + if (ret >= 0) + netdev_ethtool_info_change(dev, NULL, ETHNL_CMD_SET_PARAMS, + ETH_PARAMS_IM_COALESCE); + return ret; } static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr) @@ -1526,6 +1536,7 @@ static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr) static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr) { struct ethtool_ringparam ringparam, max = { .cmd = ETHTOOL_GRINGPARAM }; + int ret; if (!dev->ethtool_ops->set_ringparam || !dev->ethtool_ops->get_ringparam) return -EOPNOTSUPP; @@ -1542,7 +1553,11 @@ static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr) ringparam.tx_pending > max.tx_max_pending) return -EINVAL; - return dev->ethtool_ops->set_ringparam(dev, &ringparam); + ret = dev->ethtool_ops->set_ringparam(dev, &ringparam); + if (ret >= 0) + netdev_ethtool_info_change(dev, NULL, ETHNL_CMD_SET_PARAMS, + ETH_PARAMS_IM_RING); + return ret; } static noinline_for_stack int ethtool_get_channels(struct net_device *dev, @@ -1565,6 +1580,7 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev, { struct ethtool_channels channels, max = { .cmd = ETHTOOL_GCHANNELS }; u32 max_rx_in_use = 0; + int ret; if (!dev->ethtool_ops->set_channels || !dev->ethtool_ops->get_channels) return -EOPNOTSUPP; @@ -1588,7 +1604,11 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev, (channels.combined_count + channels.rx_count) <= max_rx_in_use) return -EINVAL; - return dev->ethtool_ops->set_channels(dev, &channels); + ret = dev->ethtool_ops->set_channels(dev, &channels); + if (ret >= 0) + netdev_ethtool_info_change(dev, NULL, ETHNL_CMD_SET_PARAMS, + ETH_PARAMS_IM_CHANNELS); + return ret; } static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr) @@ -1608,6 +1628,7 @@ static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr) static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr) { struct ethtool_pauseparam pauseparam; + int ret; if (!dev->ethtool_ops->set_pauseparam) return -EOPNOTSUPP; @@ -1615,7 +1636,11 @@ static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr) if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam))) return -EFAULT; - return dev->ethtool_ops->set_pauseparam(dev, &pauseparam); + ret = dev->ethtool_ops->set_pauseparam(dev, &pauseparam); + if (ret >= 0) + netdev_ethtool_info_change(dev, NULL, ETHNL_CMD_SET_PARAMS, + ETH_PARAMS_IM_PAUSE); + return ret; } static int ethtool_self_test(struct net_device *dev, char __user *useraddr) @@ -2394,6 +2419,7 @@ static int ethtool_get_fecparam(struct net_device *dev, void __user *useraddr) static int ethtool_set_fecparam(struct net_device *dev, void __user *useraddr) { struct ethtool_fecparam fecparam; + int ret; if (!dev->ethtool_ops->set_fecparam) return -EOPNOTSUPP; @@ -2401,7 +2427,11 @@ static int ethtool_set_fecparam(struct net_device *dev, void __user *useraddr) if (copy_from_user(&fecparam, useraddr, sizeof(fecparam))) return -EFAULT; - return dev->ethtool_ops->set_fecparam(dev, &fecparam); + ret = dev->ethtool_ops->set_fecparam(dev, &fecparam); + if (ret >= 0) + netdev_ethtool_info_change(dev, NULL, ETHNL_CMD_SET_PARAMS, + ETH_PARAMS_IM_FEC); + return ret; } /* The main entry point in this file. Called from net/core/dev_ioctl.c */ diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c index 721101ed2ab6..b24a0e045ec0 100644 --- a/net/ethtool/netlink.c +++ b/net/ethtool/netlink.c @@ -630,8 +630,11 @@ int ethnl_dumpit(struct sk_buff *skb, struct netlink_callback *cb) typedef void (*ethnl_notify_handler_t)(struct netdev_notifier_ethtool_info *); void ethnl_settings_notify(struct netdev_notifier_ethtool_info *); +void ethnl_params_notify(struct netdev_notifier_ethtool_info *); + ethnl_notify_handler_t ethnl_notify_handlers[] = { [ETHNL_CMD_SET_SETTINGS] = ethnl_settings_notify, + [ETHNL_CMD_SET_PARAMS] = ethnl_params_notify, }; static void __ethnl_notify(struct netdev_notifier_ethtool_info *info) diff --git a/net/ethtool/params.c b/net/ethtool/params.c index 07d4c527abf2..773e13fc1ae6 100644 --- a/net/ethtool/params.c +++ b/net/ethtool/params.c @@ -537,3 +537,43 @@ int ethnl_params_done(struct netlink_callback *cb) return 0; } + +void ethnl_params_notify(struct netdev_notifier_ethtool_info *info) +{ + struct params_reqinfo req_info = { + .dev = info->info.dev, + .req_mask = info->ethtool_info.req_mask, + .compact = true, + .have_rtnl = true, + }; + struct params_data data; + struct sk_buff *skb; + int reply_len; + void *ehdr; + int ret; + + ret = prepare_params(&data, &req_info, NULL, req_info.dev); + if (ret < 0) + return; + reply_len = params_size(&data, &req_info); + if (ret < 0) + return; + skb = genlmsg_new(reply_len, GFP_KERNEL); + if (!skb) + return; + ehdr = genlmsg_put(skb, 0, ++ethnl_bcast_seq, ðtool_genl_family, 0, + ETHNL_CMD_SET_PARAMS); + ret = ethnl_fill_dev(skb, req_info.dev, ETHA_PARAMS_DEV); + if (ret < 0) + goto err_skb; + ret = fill_params(skb, &data, &req_info); + if (ret < 0) + goto err_skb; + genlmsg_end(skb, ehdr); + + genlmsg_multicast(ðtool_genl_family, skb, 0, ETHNL_MCGRP_MONITOR, + GFP_KERNEL); + return; +err_skb: + nlmsg_free(skb); +} -- 2.18.0