From patchwork Thu May 28 23:21:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 218277 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DAC9BC433DF for ; Thu, 28 May 2020 23:21:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BD2A120721 for ; Thu, 28 May 2020 23:21:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437498AbgE1XVb (ORCPT ); Thu, 28 May 2020 19:21:31 -0400 Received: from mx2.suse.de ([195.135.220.15]:49124 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437475AbgE1XVT (ORCPT ); Thu, 28 May 2020 19:21:19 -0400 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 86EC2AFDF; Thu, 28 May 2020 23:21:17 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id AAA5DE32D2; Fri, 29 May 2020 01:21:17 +0200 (CEST) Message-Id: <66427ed9d01547b06bc7eb2b853a18108274f3eb.1590707335.git.mkubecek@suse.cz> In-Reply-To: References: From: Michal Kubecek Subject: [PATCH ethtool 02/21] netlink: fix nest type grouping in parser To: John Linville , netdev@vger.kernel.org Cc: Andrew Lunn , Oleksij Rempel Date: Fri, 29 May 2020 01:21:17 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Even if we are only interested in one nested attribute when using PARSER_GROUP_NEST group type, the temporary buffer must contain proper netlink header and have pointer to it and payload set up correctly for libmnl composition functions to be able to track current message size. Fixes: 9ee9d9517542 ("netlink: add basic command line parsing helpers") Reported-by: Andrew Lunn Signed-off-by: Michal Kubecek --- netlink/parser.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/netlink/parser.c b/netlink/parser.c index d790abedd482..bd3526f31113 100644 --- a/netlink/parser.c +++ b/netlink/parser.c @@ -957,6 +957,10 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params, if (!buff) goto out_free_buffs; msgbuff = &buff->msgbuff; + ret = msg_init(nlctx, msgbuff, parser->group, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + goto out_free_buffs; switch (group_style) { case PARSER_GROUP_NEST: @@ -966,10 +970,6 @@ int nl_parser(struct nl_context *nlctx, const struct param_parser *params, goto out_free_buffs; break; case PARSER_GROUP_MSG: - ret = msg_init(nlctx, msgbuff, parser->group, - NLM_F_REQUEST | NLM_F_ACK); - if (ret < 0) - goto out_free_buffs; if (ethnla_fill_header(msgbuff, ETHTOOL_A_LINKINFO_HEADER, nlctx->devname, 0)) From patchwork Thu May 28 23:21:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 218276 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UPPERCASE_50_75, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 58F0BC433E0 for ; Thu, 28 May 2020 23:21:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 34A8020721 for ; Thu, 28 May 2020 23:21:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437512AbgE1XVr (ORCPT ); Thu, 28 May 2020 19:21:47 -0400 Received: from mx2.suse.de ([195.135.220.15]:49250 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437494AbgE1XV3 (ORCPT ); Thu, 28 May 2020 19:21:29 -0400 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 9562AAFE8; Thu, 28 May 2020 23:21:27 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id B8CA4E32D2; Fri, 29 May 2020 01:21:27 +0200 (CEST) Message-Id: In-Reply-To: References: From: Michal Kubecek Subject: [PATCH ethtool 04/21] update UAPI header copies To: John Linville , netdev@vger.kernel.org Cc: Andrew Lunn , Oleksij Rempel Date: Fri, 29 May 2020 01:21:27 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Update to kernel v5.7-rc7. Signed-off-by: Michal Kubecek --- uapi/linux/ethtool.h | 9 +- uapi/linux/ethtool_netlink.h | 175 +++++++++++++++++++++++++++++++++++ uapi/linux/if_link.h | 6 +- uapi/linux/net_tstamp.h | 6 ++ 4 files changed, 193 insertions(+), 3 deletions(-) diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h index d3dcb459195c..c5c394899270 100644 --- a/uapi/linux/ethtool.h +++ b/uapi/linux/ethtool.h @@ -594,6 +594,9 @@ struct ethtool_pauseparam { * @ETH_SS_LINK_MODES: link mode names * @ETH_SS_MSG_CLASSES: debug message class names * @ETH_SS_WOL_MODES: wake-on-lan modes + * @ETH_SS_SOF_TIMESTAMPING: SOF_TIMESTAMPING_* flags + * @ETH_SS_TS_TX_TYPES: timestamping Tx types + * @ETH_SS_TS_RX_FILTERS: timestamping Rx filters */ enum ethtool_stringset { ETH_SS_TEST = 0, @@ -608,6 +611,9 @@ enum ethtool_stringset { ETH_SS_LINK_MODES, ETH_SS_MSG_CLASSES, ETH_SS_WOL_MODES, + ETH_SS_SOF_TIMESTAMPING, + ETH_SS_TS_TX_TYPES, + ETH_SS_TS_RX_FILTERS, /* add new constants above here */ ETH_SS_COUNT @@ -1521,8 +1527,7 @@ enum ethtool_link_mode_bit_indices { ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT = 71, ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT = 72, ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT = 73, - ETHTOOL_LINK_MODE_FEC_LLRS_BIT = 74, - + ETHTOOL_LINK_MODE_FEC_LLRS_BIT = 74, /* must be last entry */ __ETHTOOL_LINK_MODE_MASK_NBITS }; diff --git a/uapi/linux/ethtool_netlink.h b/uapi/linux/ethtool_netlink.h index ad6d3a00019d..10061e4b16d9 100644 --- a/uapi/linux/ethtool_netlink.h +++ b/uapi/linux/ethtool_netlink.h @@ -24,6 +24,21 @@ enum { ETHTOOL_MSG_DEBUG_SET, ETHTOOL_MSG_WOL_GET, ETHTOOL_MSG_WOL_SET, + ETHTOOL_MSG_FEATURES_GET, + ETHTOOL_MSG_FEATURES_SET, + ETHTOOL_MSG_PRIVFLAGS_GET, + ETHTOOL_MSG_PRIVFLAGS_SET, + ETHTOOL_MSG_RINGS_GET, + ETHTOOL_MSG_RINGS_SET, + ETHTOOL_MSG_CHANNELS_GET, + ETHTOOL_MSG_CHANNELS_SET, + ETHTOOL_MSG_COALESCE_GET, + ETHTOOL_MSG_COALESCE_SET, + ETHTOOL_MSG_PAUSE_GET, + ETHTOOL_MSG_PAUSE_SET, + ETHTOOL_MSG_EEE_GET, + ETHTOOL_MSG_EEE_SET, + ETHTOOL_MSG_TSINFO_GET, /* add new constants above here */ __ETHTOOL_MSG_USER_CNT, @@ -43,6 +58,22 @@ enum { ETHTOOL_MSG_DEBUG_NTF, ETHTOOL_MSG_WOL_GET_REPLY, ETHTOOL_MSG_WOL_NTF, + ETHTOOL_MSG_FEATURES_GET_REPLY, + ETHTOOL_MSG_FEATURES_SET_REPLY, + ETHTOOL_MSG_FEATURES_NTF, + ETHTOOL_MSG_PRIVFLAGS_GET_REPLY, + ETHTOOL_MSG_PRIVFLAGS_NTF, + ETHTOOL_MSG_RINGS_GET_REPLY, + ETHTOOL_MSG_RINGS_NTF, + ETHTOOL_MSG_CHANNELS_GET_REPLY, + ETHTOOL_MSG_CHANNELS_NTF, + ETHTOOL_MSG_COALESCE_GET_REPLY, + ETHTOOL_MSG_COALESCE_NTF, + ETHTOOL_MSG_PAUSE_GET_REPLY, + ETHTOOL_MSG_PAUSE_NTF, + ETHTOOL_MSG_EEE_GET_REPLY, + ETHTOOL_MSG_EEE_NTF, + ETHTOOL_MSG_TSINFO_GET_REPLY, /* add new constants above here */ __ETHTOOL_MSG_KERNEL_CNT, @@ -228,6 +259,150 @@ enum { ETHTOOL_A_WOL_MAX = __ETHTOOL_A_WOL_CNT - 1 }; +/* FEATURES */ + +enum { + ETHTOOL_A_FEATURES_UNSPEC, + ETHTOOL_A_FEATURES_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_FEATURES_HW, /* bitset */ + ETHTOOL_A_FEATURES_WANTED, /* bitset */ + ETHTOOL_A_FEATURES_ACTIVE, /* bitset */ + ETHTOOL_A_FEATURES_NOCHANGE, /* bitset */ + + /* add new constants above here */ + __ETHTOOL_A_FEATURES_CNT, + ETHTOOL_A_FEATURES_MAX = __ETHTOOL_A_FEATURES_CNT - 1 +}; + +/* PRIVFLAGS */ + +enum { + ETHTOOL_A_PRIVFLAGS_UNSPEC, + ETHTOOL_A_PRIVFLAGS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PRIVFLAGS_FLAGS, /* bitset */ + + /* add new constants above here */ + __ETHTOOL_A_PRIVFLAGS_CNT, + ETHTOOL_A_PRIVFLAGS_MAX = __ETHTOOL_A_PRIVFLAGS_CNT - 1 +}; + +/* RINGS */ + +enum { + ETHTOOL_A_RINGS_UNSPEC, + ETHTOOL_A_RINGS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_RINGS_RX_MAX, /* u32 */ + ETHTOOL_A_RINGS_RX_MINI_MAX, /* u32 */ + ETHTOOL_A_RINGS_RX_JUMBO_MAX, /* u32 */ + ETHTOOL_A_RINGS_TX_MAX, /* u32 */ + ETHTOOL_A_RINGS_RX, /* u32 */ + ETHTOOL_A_RINGS_RX_MINI, /* u32 */ + ETHTOOL_A_RINGS_RX_JUMBO, /* u32 */ + ETHTOOL_A_RINGS_TX, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_RINGS_CNT, + ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1) +}; + +/* CHANNELS */ + +enum { + ETHTOOL_A_CHANNELS_UNSPEC, + ETHTOOL_A_CHANNELS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_CHANNELS_RX_MAX, /* u32 */ + ETHTOOL_A_CHANNELS_TX_MAX, /* u32 */ + ETHTOOL_A_CHANNELS_OTHER_MAX, /* u32 */ + ETHTOOL_A_CHANNELS_COMBINED_MAX, /* u32 */ + ETHTOOL_A_CHANNELS_RX_COUNT, /* u32 */ + ETHTOOL_A_CHANNELS_TX_COUNT, /* u32 */ + ETHTOOL_A_CHANNELS_OTHER_COUNT, /* u32 */ + ETHTOOL_A_CHANNELS_COMBINED_COUNT, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_CHANNELS_CNT, + ETHTOOL_A_CHANNELS_MAX = (__ETHTOOL_A_CHANNELS_CNT - 1) +}; + +/* COALESCE */ + +enum { + ETHTOOL_A_COALESCE_UNSPEC, + ETHTOOL_A_COALESCE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_COALESCE_RX_USECS, /* u32 */ + ETHTOOL_A_COALESCE_RX_MAX_FRAMES, /* u32 */ + ETHTOOL_A_COALESCE_RX_USECS_IRQ, /* u32 */ + ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ, /* u32 */ + ETHTOOL_A_COALESCE_TX_USECS, /* u32 */ + ETHTOOL_A_COALESCE_TX_MAX_FRAMES, /* u32 */ + ETHTOOL_A_COALESCE_TX_USECS_IRQ, /* u32 */ + ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ, /* u32 */ + ETHTOOL_A_COALESCE_STATS_BLOCK_USECS, /* u32 */ + ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX, /* u8 */ + ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX, /* u8 */ + ETHTOOL_A_COALESCE_PKT_RATE_LOW, /* u32 */ + ETHTOOL_A_COALESCE_RX_USECS_LOW, /* u32 */ + ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW, /* u32 */ + ETHTOOL_A_COALESCE_TX_USECS_LOW, /* u32 */ + ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW, /* u32 */ + ETHTOOL_A_COALESCE_PKT_RATE_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_RX_USECS_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_TX_USECS_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_COALESCE_CNT, + ETHTOOL_A_COALESCE_MAX = (__ETHTOOL_A_COALESCE_CNT - 1) +}; + +/* PAUSE */ + +enum { + ETHTOOL_A_PAUSE_UNSPEC, + ETHTOOL_A_PAUSE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PAUSE_AUTONEG, /* u8 */ + ETHTOOL_A_PAUSE_RX, /* u8 */ + ETHTOOL_A_PAUSE_TX, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_PAUSE_CNT, + ETHTOOL_A_PAUSE_MAX = (__ETHTOOL_A_PAUSE_CNT - 1) +}; + +/* EEE */ + +enum { + ETHTOOL_A_EEE_UNSPEC, + ETHTOOL_A_EEE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_EEE_MODES_OURS, /* bitset */ + ETHTOOL_A_EEE_MODES_PEER, /* bitset */ + ETHTOOL_A_EEE_ACTIVE, /* u8 */ + ETHTOOL_A_EEE_ENABLED, /* u8 */ + ETHTOOL_A_EEE_TX_LPI_ENABLED, /* u8 */ + ETHTOOL_A_EEE_TX_LPI_TIMER, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_EEE_CNT, + ETHTOOL_A_EEE_MAX = (__ETHTOOL_A_EEE_CNT - 1) +}; + +/* TSINFO */ + +enum { + ETHTOOL_A_TSINFO_UNSPEC, + ETHTOOL_A_TSINFO_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_TSINFO_TIMESTAMPING, /* bitset */ + ETHTOOL_A_TSINFO_TX_TYPES, /* bitset */ + ETHTOOL_A_TSINFO_RX_FILTERS, /* bitset */ + ETHTOOL_A_TSINFO_PHC_INDEX, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_TSINFO_CNT, + ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1) +}; + /* generic netlink info */ #define ETHTOOL_GENL_NAME "ethtool" #define ETHTOOL_GENL_VERSION 1 diff --git a/uapi/linux/if_link.h b/uapi/linux/if_link.h index cb88bcb47287..978f98c76be1 100644 --- a/uapi/linux/if_link.h +++ b/uapi/linux/if_link.h @@ -461,6 +461,7 @@ enum { IFLA_MACSEC_REPLAY_PROTECT, IFLA_MACSEC_VALIDATION, IFLA_MACSEC_PAD, + IFLA_MACSEC_OFFLOAD, __IFLA_MACSEC_MAX, }; @@ -487,6 +488,7 @@ enum macsec_validation_type { enum macsec_offload { MACSEC_OFFLOAD_OFF = 0, MACSEC_OFFLOAD_PHY = 1, + MACSEC_OFFLOAD_MAC = 2, __MACSEC_OFFLOAD_END, MACSEC_OFFLOAD_MAX = __MACSEC_OFFLOAD_END - 1, }; @@ -970,11 +972,12 @@ enum { #define XDP_FLAGS_SKB_MODE (1U << 1) #define XDP_FLAGS_DRV_MODE (1U << 2) #define XDP_FLAGS_HW_MODE (1U << 3) +#define XDP_FLAGS_REPLACE (1U << 4) #define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | \ XDP_FLAGS_DRV_MODE | \ XDP_FLAGS_HW_MODE) #define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \ - XDP_FLAGS_MODES) + XDP_FLAGS_MODES | XDP_FLAGS_REPLACE) /* These are stored into IFLA_XDP_ATTACHED on dump. */ enum { @@ -994,6 +997,7 @@ enum { IFLA_XDP_DRV_PROG_ID, IFLA_XDP_SKB_PROG_ID, IFLA_XDP_HW_PROG_ID, + IFLA_XDP_EXPECTED_FD, __IFLA_XDP_MAX, }; diff --git a/uapi/linux/net_tstamp.h b/uapi/linux/net_tstamp.h index f96e650d0af9..7ed0b3d1c00a 100644 --- a/uapi/linux/net_tstamp.h +++ b/uapi/linux/net_tstamp.h @@ -98,6 +98,9 @@ enum hwtstamp_tx_types { * receive a time stamp via the socket error queue. */ HWTSTAMP_TX_ONESTEP_P2P, + + /* add new constants above here */ + __HWTSTAMP_TX_CNT }; /* possible values for hwtstamp_config->rx_filter */ @@ -140,6 +143,9 @@ enum hwtstamp_rx_filters { /* NTP, UDP, all versions and packet modes */ HWTSTAMP_FILTER_NTP_ALL, + + /* add new constants above here */ + __HWTSTAMP_FILTER_CNT }; /* SCM_TIMESTAMPING_PKTINFO control message */ From patchwork Thu May 28 23:21:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 218275 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EA20DC433DF for ; Thu, 28 May 2020 23:21:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CE90E2084C for ; Thu, 28 May 2020 23:21:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437522AbgE1XV5 (ORCPT ); Thu, 28 May 2020 19:21:57 -0400 Received: from mx2.suse.de ([195.135.220.15]:49300 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437506AbgE1XVj (ORCPT ); Thu, 28 May 2020 19:21:39 -0400 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 A64D3AFED; Thu, 28 May 2020 23:21:37 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id C6732E32D2; Fri, 29 May 2020 01:21:37 +0200 (CEST) Message-Id: <6c672d7a5d3b598cb8c8de5b624db87ab67a0176.1590707335.git.mkubecek@suse.cz> In-Reply-To: References: From: Michal Kubecek Subject: [PATCH ethtool 06/21] selftest: omit test-features if netlink is enabled To: John Linville , netdev@vger.kernel.org Cc: Andrew Lunn , Oleksij Rempel Date: Fri, 29 May 2020 01:21:37 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The test-features selftest is checking data structures passed to ioctl() syscall. Therefore a complete rework of the test framework will be needed to be able to perform an equivalent selftest for netlink interface. Until such framework is implemented, disable test-features when building ethtool with netlink support. Signed-off-by: Michal Kubecek --- Makefile.am | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 0f8465f7ada9..b3ffae52f1e9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -40,12 +40,16 @@ AM_CPPFLAGS += @MNL_CFLAGS@ LDADD += @MNL_LIBS@ endif -TESTS = test-cmdline test-features -check_PROGRAMS = test-cmdline test-features +TESTS = test-cmdline +check_PROGRAMS = test-cmdline test_cmdline_SOURCES = test-cmdline.c test-common.c $(ethtool_SOURCES) test_cmdline_CFLAGS = -DTEST_ETHTOOL +if !ETHTOOL_ENABLE_NETLINK +TESTS += test-features +check_PROGRAMS += test-features test_features_SOURCES = test-features.c test-common.c $(ethtool_SOURCES) test_features_CFLAGS = -DTEST_ETHTOOL +endif dist-hook: cp $(top_srcdir)/ethtool.spec $(distdir) From patchwork Thu May 28 23:21:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 218274 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B33B0C433E0 for ; Thu, 28 May 2020 23:22:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8AC5220721 for ; Thu, 28 May 2020 23:22:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437532AbgE1XWD (ORCPT ); Thu, 28 May 2020 19:22:03 -0400 Received: from mx2.suse.de ([195.135.220.15]:49314 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437509AbgE1XVr (ORCPT ); Thu, 28 May 2020 19:21:47 -0400 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 AFBB7AFEF; Thu, 28 May 2020 23:21:42 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id CD5ABE32D2; Fri, 29 May 2020 01:21:42 +0200 (CEST) Message-Id: <75c256f1009f9b6e1a0402343c7780103f01ae4b.1590707335.git.mkubecek@suse.cz> In-Reply-To: References: From: Michal Kubecek Subject: [PATCH ethtool 07/21] netlink: add netlink handler for gfeatures (-k) To: John Linville , netdev@vger.kernel.org Cc: Andrew Lunn , Oleksij Rempel Date: Fri, 29 May 2020 01:21:42 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Implement "ethtool -k " subcommand using ETHTOOL_MSG_FEATURES_GET netlink message. This retrieves and displays names and values of netdev feature flags, traditionally provided by ioctl request ETHTOOL_GFEATURES (and some older ones). Unlike ioctl, the netlink code does not query kernel for values of legacy flags (ETH_FLAG_*) and computes their value from features grouped under such flag instead so that it can get slightly different results than ioctl implementation in cases where some new feature is not considered by kernel code (kernel fix is going to be submitted soon). This commit also registers the callback with monitor code so that the monitor can display ETHTOOL_MSG_FEATURES_NTF notifications. Signed-off-by: Michal Kubecek --- Makefile.am | 1 + common.c | 30 ++++++ common.h | 19 ++++ ethtool.c | 65 ++---------- netlink/bitset.c | 18 ++++ netlink/bitset.h | 1 + netlink/extapi.h | 2 + netlink/features.c | 241 +++++++++++++++++++++++++++++++++++++++++++++ netlink/monitor.c | 8 ++ netlink/netlink.h | 1 + 10 files changed, 331 insertions(+), 55 deletions(-) create mode 100644 netlink/features.c diff --git a/Makefile.am b/Makefile.am index b3ffae52f1e9..36ee50a9dd0c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,6 +31,7 @@ ethtool_SOURCES += \ netlink/monitor.c netlink/bitset.c netlink/bitset.h \ netlink/settings.c netlink/parser.c netlink/parser.h \ netlink/permaddr.c netlink/prettymsg.c netlink/prettymsg.h \ + netlink/features.c \ netlink/desc-ethtool.c netlink/desc-genlctrl.c \ netlink/desc-rtnl.c \ uapi/linux/ethtool_netlink.h \ diff --git a/common.c b/common.c index f9c41a32d3a3..2630e73aa601 100644 --- a/common.c +++ b/common.c @@ -47,6 +47,36 @@ const struct flag_info flags_msglvl[] = { }; const unsigned int n_flags_msglvl = ARRAY_SIZE(flags_msglvl) - 1; +const struct off_flag_def off_flag_def[] = { + { "rx", "rx-checksumming", "rx-checksum", + ETHTOOL_GRXCSUM, ETHTOOL_SRXCSUM, ETH_FLAG_RXCSUM, 0 }, + { "tx", "tx-checksumming", "tx-checksum-*", + ETHTOOL_GTXCSUM, ETHTOOL_STXCSUM, ETH_FLAG_TXCSUM, 0 }, + { "sg", "scatter-gather", "tx-scatter-gather*", + ETHTOOL_GSG, ETHTOOL_SSG, ETH_FLAG_SG, 0 }, + { "tso", "tcp-segmentation-offload", "tx-tcp*-segmentation", + ETHTOOL_GTSO, ETHTOOL_STSO, ETH_FLAG_TSO, 0 }, + { "ufo", "udp-fragmentation-offload", "tx-udp-fragmentation", + ETHTOOL_GUFO, ETHTOOL_SUFO, ETH_FLAG_UFO, 0 }, + { "gso", "generic-segmentation-offload", "tx-generic-segmentation", + ETHTOOL_GGSO, ETHTOOL_SGSO, ETH_FLAG_GSO, 0 }, + { "gro", "generic-receive-offload", "rx-gro", + ETHTOOL_GGRO, ETHTOOL_SGRO, ETH_FLAG_GRO, 0 }, + { "lro", "large-receive-offload", "rx-lro", + 0, 0, ETH_FLAG_LRO, + KERNEL_VERSION(2,6,24) }, + { "rxvlan", "rx-vlan-offload", "rx-vlan-hw-parse", + 0, 0, ETH_FLAG_RXVLAN, + KERNEL_VERSION(2,6,37) }, + { "txvlan", "tx-vlan-offload", "tx-vlan-hw-insert", + 0, 0, ETH_FLAG_TXVLAN, + KERNEL_VERSION(2,6,37) }, + { "ntuple", "ntuple-filters", "rx-ntuple-filter", + 0, 0, ETH_FLAG_NTUPLE, 0 }, + { "rxhash", "receive-hashing", "rx-hashing", + 0, 0, ETH_FLAG_RXHASH, 0 }, +}; + void print_flags(const struct flag_info *info, unsigned int n_info, u32 value) { const char *sep = ""; diff --git a/common.h b/common.h index 3a680114a7c2..b74fdfa030b3 100644 --- a/common.h +++ b/common.h @@ -19,6 +19,25 @@ struct flag_info { extern const struct flag_info flags_msglvl[]; extern const unsigned int n_flags_msglvl; +struct off_flag_def { + const char *short_name; + const char *long_name; + const char *kernel_name; + u32 get_cmd, set_cmd; + u32 value; + /* For features exposed through ETHTOOL_GFLAGS, the oldest + * kernel version for which we can trust the result. Where + * the flag was added at the same time the kernel started + * supporting the feature, this is 0 (to allow for backports). + * Where the feature was supported before the flag was added, + * it is the version that introduced the flag. + */ + u32 min_kernel_ver; +}; + +#define OFF_FLAG_DEF_SIZE 12 +extern const struct off_flag_def off_flag_def[OFF_FLAG_DEF_SIZE]; + void print_flags(const struct flag_info *info, unsigned int n_info, u32 value); int dump_wol(struct ethtool_wolinfo *wol); void dump_mdix(u8 mdix, u8 mdix_ctrl); diff --git a/ethtool.c b/ethtool.c index 900880aff8d6..4749f3ae52a5 100644 --- a/ethtool.c +++ b/ethtool.c @@ -102,51 +102,6 @@ struct cmdline_info { void *seen_val; }; -struct off_flag_def { - const char *short_name; - const char *long_name; - const char *kernel_name; - u32 get_cmd, set_cmd; - u32 value; - /* For features exposed through ETHTOOL_GFLAGS, the oldest - * kernel version for which we can trust the result. Where - * the flag was added at the same time the kernel started - * supporting the feature, this is 0 (to allow for backports). - * Where the feature was supported before the flag was added, - * it is the version that introduced the flag. - */ - u32 min_kernel_ver; -}; -static const struct off_flag_def off_flag_def[] = { - { "rx", "rx-checksumming", "rx-checksum", - ETHTOOL_GRXCSUM, ETHTOOL_SRXCSUM, ETH_FLAG_RXCSUM, 0 }, - { "tx", "tx-checksumming", "tx-checksum-*", - ETHTOOL_GTXCSUM, ETHTOOL_STXCSUM, ETH_FLAG_TXCSUM, 0 }, - { "sg", "scatter-gather", "tx-scatter-gather*", - ETHTOOL_GSG, ETHTOOL_SSG, ETH_FLAG_SG, 0 }, - { "tso", "tcp-segmentation-offload", "tx-tcp*-segmentation", - ETHTOOL_GTSO, ETHTOOL_STSO, ETH_FLAG_TSO, 0 }, - { "ufo", "udp-fragmentation-offload", "tx-udp-fragmentation", - ETHTOOL_GUFO, ETHTOOL_SUFO, ETH_FLAG_UFO, 0 }, - { "gso", "generic-segmentation-offload", "tx-generic-segmentation", - ETHTOOL_GGSO, ETHTOOL_SGSO, ETH_FLAG_GSO, 0 }, - { "gro", "generic-receive-offload", "rx-gro", - ETHTOOL_GGRO, ETHTOOL_SGRO, ETH_FLAG_GRO, 0 }, - { "lro", "large-receive-offload", "rx-lro", - 0, 0, ETH_FLAG_LRO, - KERNEL_VERSION(2,6,24) }, - { "rxvlan", "rx-vlan-offload", "rx-vlan-hw-parse", - 0, 0, ETH_FLAG_RXVLAN, - KERNEL_VERSION(2,6,37) }, - { "txvlan", "tx-vlan-offload", "tx-vlan-hw-insert", - 0, 0, ETH_FLAG_TXVLAN, - KERNEL_VERSION(2,6,37) }, - { "ntuple", "ntuple-filters", "rx-ntuple-filter", - 0, 0, ETH_FLAG_NTUPLE, 0 }, - { "rxhash", "receive-hashing", "rx-hashing", - 0, 0, ETH_FLAG_RXHASH, 0 }, -}; - struct feature_def { char name[ETH_GSTRING_LEN]; int off_flag_index; /* index in off_flag_def; negative if none match */ @@ -155,7 +110,7 @@ struct feature_def { struct feature_defs { size_t n_features; /* Number of features each offload flag is associated with */ - unsigned int off_flag_matched[ARRAY_SIZE(off_flag_def)]; + unsigned int off_flag_matched[OFF_FLAG_DEF_SIZE]; /* Name and offload flag index for each feature */ struct feature_def def[0]; }; @@ -1423,7 +1378,7 @@ static void dump_features(const struct feature_defs *defs, int indent; int i, j; - for (i = 0; i < ARRAY_SIZE(off_flag_def); i++) { + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { /* Don't show features whose state is unknown on this * kernel version */ @@ -1742,7 +1697,7 @@ static struct feature_defs *get_feature_defs(struct cmd_context *ctx) defs->def[i].off_flag_index = -1; for (j = 0; - j < ARRAY_SIZE(off_flag_def) && + j < OFF_FLAG_DEF_SIZE && defs->def[i].off_flag_index < 0; j++) { const char *pattern = @@ -2190,7 +2145,7 @@ get_features(struct cmd_context *ctx, const struct feature_defs *defs) state->off_flags = 0; - for (i = 0; i < ARRAY_SIZE(off_flag_def); i++) { + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { value = off_flag_def[i].value; if (!off_flag_def[i].get_cmd) continue; @@ -2306,8 +2261,7 @@ static int do_sfeatures(struct cmd_context *ctx) /* Generate cmdline_info for legacy flags and kernel-named * features, and parse our arguments. */ - cmdline_features = calloc(2 * ARRAY_SIZE(off_flag_def) + - defs->n_features, + cmdline_features = calloc(2 * OFF_FLAG_DEF_SIZE + defs->n_features, sizeof(cmdline_features[0])); if (!cmdline_features) { perror("Cannot parse arguments"); @@ -2315,7 +2269,7 @@ static int do_sfeatures(struct cmd_context *ctx) goto err; } j = 0; - for (i = 0; i < ARRAY_SIZE(off_flag_def); i++) { + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { flag_to_cmdline_info(off_flag_def[i].short_name, off_flag_def[i].value, &off_flags_wanted, &off_flags_mask, @@ -2332,7 +2286,7 @@ static int do_sfeatures(struct cmd_context *ctx) &FEATURE_WORD(efeatures->features, i, valid), &cmdline_features[j++]); parse_generic_cmdline(ctx, &any_changed, cmdline_features, - 2 * ARRAY_SIZE(off_flag_def) + defs->n_features); + 2 * OFF_FLAG_DEF_SIZE + defs->n_features); free(cmdline_features); if (!any_changed) { @@ -2352,7 +2306,7 @@ static int do_sfeatures(struct cmd_context *ctx) * related features that the user did not specify and that * are not fixed. Warn if all related features are fixed. */ - for (i = 0; i < ARRAY_SIZE(off_flag_def); i++) { + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { int fixed = 1; if (!(off_flags_mask & off_flag_def[i].value)) @@ -2393,7 +2347,7 @@ static int do_sfeatures(struct cmd_context *ctx) goto err; } } else { - for (i = 0; i < ARRAY_SIZE(off_flag_def); i++) { + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { if (!off_flag_def[i].set_cmd) continue; if (off_flags_mask & off_flag_def[i].value) { @@ -5259,6 +5213,7 @@ static const struct option args[] = { { .opts = "-k|--show-features|--show-offload", .func = do_gfeatures, + .nlfunc = nl_gfeatures, .help = "Get state of protocol offload and other features" }, { diff --git a/netlink/bitset.c b/netlink/bitset.c index ed109ec1d2c0..291ac7170272 100644 --- a/netlink/bitset.c +++ b/netlink/bitset.c @@ -153,6 +153,24 @@ err: return true; } +uint32_t *get_compact_bitset_value(const struct nlattr *bitset) +{ + const struct nlattr *tb[ETHTOOL_A_BITSET_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + unsigned int count; + int ret; + + ret = mnl_attr_parse_nested(bitset, attr_cb, &tb_info); + if (ret < 0 || + !tb[ETHTOOL_A_BITSET_SIZE] || !tb[ETHTOOL_A_BITSET_VALUE]) + return NULL; + count = mnl_attr_get_u32(tb[ETHTOOL_A_BITSET_SIZE]); + if (8 * mnl_attr_get_payload_len(tb[ETHTOOL_A_BITSET_VALUE]) < count) + return NULL; + + return mnl_attr_get_payload(tb[ETHTOOL_A_BITSET_VALUE]); +} + int walk_bitset(const struct nlattr *bitset, const struct stringset *labels, bitset_walk_callback cb, void *data) { diff --git a/netlink/bitset.h b/netlink/bitset.h index 4b587d2c8a04..9f3230981e40 100644 --- a/netlink/bitset.h +++ b/netlink/bitset.h @@ -20,6 +20,7 @@ bool bitset_get_bit(const struct nlattr *bitset, bool mask, unsigned int idx, int *retptr); bool bitset_is_compact(const struct nlattr *bitset); bool bitset_is_empty(const struct nlattr *bitset, bool mask, int *retptr); +uint32_t *get_compact_bitset_value(const struct nlattr *bitset); int walk_bitset(const struct nlattr *bitset, const struct stringset *labels, bitset_walk_callback cb, void *data); diff --git a/netlink/extapi.h b/netlink/extapi.h index 9484b4c5ae7e..81c1de0df1e6 100644 --- a/netlink/extapi.h +++ b/netlink/extapi.h @@ -20,6 +20,7 @@ void netlink_run_handler(struct cmd_context *ctx, nl_func_t nlfunc, int nl_gset(struct cmd_context *ctx); int nl_sset(struct cmd_context *ctx); int nl_permaddr(struct cmd_context *ctx); +int nl_gfeatures(struct cmd_context *ctx); int nl_monitor(struct cmd_context *ctx); void nl_monitor_usage(void); @@ -44,6 +45,7 @@ static inline void nl_monitor_usage(void) #define nl_gset NULL #define nl_sset NULL #define nl_permaddr NULL +#define nl_gfeatures NULL #endif /* ETHTOOL_ENABLE_NETLINK */ diff --git a/netlink/features.c b/netlink/features.c new file mode 100644 index 000000000000..76c16dbf2e13 --- /dev/null +++ b/netlink/features.c @@ -0,0 +1,241 @@ +/* + * features.c - netlink implementation of netdev features commands + * + * Implementation of "ethtool -k ". + */ + +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "strset.h" +#include "bitset.h" + +/* FEATURES_GET */ + +struct feature_results { + uint32_t *hw; + uint32_t *wanted; + uint32_t *active; + uint32_t *nochange; + unsigned int count; + unsigned int words; +}; + +static int prepare_feature_results(const struct nlattr *const *tb, + struct feature_results *dest) +{ + unsigned int count; + int ret; + + memset(dest, '\0', sizeof(*dest)); + if (!tb[ETHTOOL_A_FEATURES_HW] || !tb[ETHTOOL_A_FEATURES_WANTED] || + !tb[ETHTOOL_A_FEATURES_ACTIVE] || !tb[ETHTOOL_A_FEATURES_NOCHANGE]) + return -EFAULT; + count = bitset_get_count(tb[ETHTOOL_A_FEATURES_HW], &ret); + if (ret < 0) + return -EFAULT; + if ((bitset_get_count(tb[ETHTOOL_A_FEATURES_WANTED], &ret) != count) || + (bitset_get_count(tb[ETHTOOL_A_FEATURES_ACTIVE], &ret) != count) || + (bitset_get_count(tb[ETHTOOL_A_FEATURES_NOCHANGE], &ret) != count)) + return -EFAULT; + dest->hw = get_compact_bitset_value(tb[ETHTOOL_A_FEATURES_HW]); + dest->wanted = get_compact_bitset_value(tb[ETHTOOL_A_FEATURES_WANTED]); + dest->active = get_compact_bitset_value(tb[ETHTOOL_A_FEATURES_ACTIVE]); + dest->nochange = + get_compact_bitset_value(tb[ETHTOOL_A_FEATURES_NOCHANGE]); + if (!dest->hw || !dest->wanted || !dest->active || !dest->nochange) + return -EFAULT; + dest->count = count; + dest->words = (count + 31) / 32; + + return 0; +} + +static bool feature_on(const uint32_t *bitmap, unsigned int idx) +{ + return bitmap[idx / 32] & (1 << (idx % 32)); +} + +static void dump_feature(const struct feature_results *results, + const uint32_t *ref, const uint32_t *ref_mask, + unsigned int idx, const char *name, const char *prefix) +{ + const char *suffix = ""; + + if (!name || !*name) + return; + if (ref) { + if (ref_mask && !feature_on(ref_mask, idx)) + return; + if ((!ref_mask || feature_on(ref_mask, idx)) && + (feature_on(results->active, idx) == feature_on(ref, idx))) + return; + } + + if (!feature_on(results->hw, idx) || feature_on(results->nochange, idx)) + suffix = " [fixed]"; + else if (feature_on(results->active, idx) != + feature_on(results->wanted, idx)) + suffix = feature_on(results->wanted, idx) ? + " [requested on]" : " [requested off]"; + printf("%s%s: %s%s\n", prefix, name, + feature_on(results->active, idx) ? "on" : "off", suffix); +} + +/* this assumes pattern contains no more than one asterisk */ +static bool flag_pattern_match(const char *name, const char *pattern) +{ + const char *p_ast = strchr(pattern, '*'); + + if (p_ast) { + size_t name_len = strlen(name); + size_t pattern_len = strlen(pattern); + + if (name_len + 1 < pattern_len) + return false; + if (strncmp(name, pattern, p_ast - pattern)) + return false; + pattern_len -= (p_ast - pattern) + 1; + name += name_len - pattern_len; + pattern = p_ast + 1; + } + return !strcmp(name, pattern); +} + +int dump_features(const struct nlattr *const *tb, + const struct stringset *feature_names) +{ + struct feature_results results; + unsigned int i, j; + int *feature_flags = NULL; + int ret; + + ret = prepare_feature_results(tb, &results); + if (ret < 0) + return -EFAULT; + + ret = -ENOMEM; + feature_flags = calloc(results.count, sizeof(feature_flags[0])); + if (!feature_flags) + goto out_free; + + /* map netdev features to legacy flags */ + for (i = 0; i < results.count; i++) { + const char *name = get_string(feature_names, i); + feature_flags[i] = -1; + + if (!name || !*name) + continue; + for (j = 0; j < OFF_FLAG_DEF_SIZE; j++) { + const char *flag_name = off_flag_def[j].kernel_name; + + if (flag_pattern_match(name, flag_name)) { + feature_flags[i] = j; + break; + } + } + } + /* show legacy flags and their matching features first */ + for (i = 0; i < OFF_FLAG_DEF_SIZE; i++) { + unsigned int n_match = 0; + bool flag_value = false; + + /* no kernel with netlink interface supports UFO */ + if (off_flag_def[i].value == ETH_FLAG_UFO) + continue; + + for (j = 0; j < results.count; j++) { + if (feature_flags[j] == i) { + n_match++; + flag_value = flag_value || + feature_on(results.active, j); + } + } + if (n_match != 1) + printf("%s: %s\n", off_flag_def[i].long_name, + flag_value ? "on" : "off"); + if (n_match == 0) + continue; + for (j = 0; j < results.count; j++) { + const char *name = get_string(feature_names, j); + + if (feature_flags[j] != i) + continue; + if (n_match == 1) + dump_feature(&results, NULL, NULL, j, + off_flag_def[i].long_name, ""); + else + dump_feature(&results, NULL, NULL, j, name, + "\t"); + } + } + /* and, finally, remaining netdev_features not matching legacy flags */ + for (i = 0; i < results.count; i++) { + const char *name = get_string(feature_names, i); + + if (!name || !*name || feature_flags[i] >= 0) + continue; + dump_feature(&results, NULL, NULL, i, name, ""); + } + +out_free: + free(feature_flags); + return 0; +} + +int features_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_FEATURES_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + const struct stringset *feature_names; + struct nl_context *nlctx = data; + bool silent; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + if (!nlctx->is_monitor) { + ret = netlink_init_ethnl2_socket(nlctx); + if (ret < 0) + return MNL_CB_ERROR; + } + feature_names = global_stringset(ETH_SS_FEATURES, nlctx->ethnl2_socket); + + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return silent ? MNL_CB_OK : MNL_CB_ERROR; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_FEATURES_HEADER]); + if (!dev_ok(nlctx)) + return MNL_CB_OK; + + if (silent) + putchar('\n'); + printf("Features for %s:\n", nlctx->devname); + ret = dump_features(tb, feature_names); + return (silent || !ret) ? MNL_CB_OK : MNL_CB_ERROR; +} + +int nl_gfeatures(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_FEATURES_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_FEATURES_GET, + ETHTOOL_A_FEATURES_HEADER, + ETHTOOL_FLAG_COMPACT_BITSETS); + if (ret < 0) + return ret; + return nlsock_send_get_request(nlsk, features_reply_cb); +} diff --git a/netlink/monitor.c b/netlink/monitor.c index e20db5fc79d4..a572e3c38463 100644 --- a/netlink/monitor.c +++ b/netlink/monitor.c @@ -31,6 +31,10 @@ static struct { .cmd = ETHTOOL_MSG_DEBUG_NTF, .cb = debug_reply_cb, }, + { + .cmd = ETHTOOL_MSG_FEATURES_NTF, + .cb = features_reply_cb, + }, }; static void clear_filter(struct nl_context *nlctx) @@ -102,6 +106,10 @@ static struct monitor_option monitor_opts[] = { .pattern = "-s|--change", .cmd = ETHTOOL_MSG_DEBUG_NTF, }, + { + .pattern = "-k|--show-features|--show-offload|-K|--features|--offload", + .cmd = ETHTOOL_MSG_FEATURES_NTF, + }, }; static bool pattern_match(const char *s, const char *pattern) diff --git a/netlink/netlink.h b/netlink/netlink.h index 4419be0f751a..98e38ff2d7b0 100644 --- a/netlink/netlink.h +++ b/netlink/netlink.h @@ -62,6 +62,7 @@ int linkmodes_reply_cb(const struct nlmsghdr *nlhdr, void *data); int linkinfo_reply_cb(const struct nlmsghdr *nlhdr, void *data); int wol_reply_cb(const struct nlmsghdr *nlhdr, void *data); int debug_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int features_reply_cb(const struct nlmsghdr *nlhdr, void *data); static inline void copy_devname(char *dst, const char *src) { From patchwork Thu May 28 23:21:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 218273 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3FB12C433E0 for ; Thu, 28 May 2020 23:22:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 238BA20721 for ; Thu, 28 May 2020 23:22:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437540AbgE1XWM (ORCPT ); Thu, 28 May 2020 19:22:12 -0400 Received: from mx2.suse.de ([195.135.220.15]:49424 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437524AbgE1XWA (ORCPT ); Thu, 28 May 2020 19:22:00 -0400 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 C03F4AFF4; Thu, 28 May 2020 23:21:57 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id E1EB9E32D2; Fri, 29 May 2020 01:21:57 +0200 (CEST) Message-Id: <1b897e33f5f792729deb0750fceab5394abc32fd.1590707335.git.mkubecek@suse.cz> In-Reply-To: References: From: Michal Kubecek Subject: [PATCH ethtool 10/21] netlink: add netlink handler for sprivflags (--set-priv-flags) To: John Linville , netdev@vger.kernel.org Cc: Andrew Lunn , Oleksij Rempel Date: Fri, 29 May 2020 01:21:57 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Implement "ethtool --set-priv-flags ..." subcommand to set device private flags using ETHTOOL_MSG_PRIVFLAGS_SET netlink message. These are traditionally set using ETHTOOL_SPFLAGS ioctl request. Unlike ioctl implementation, netlink does not retrieve private flag names first so that names provided on command line are validated by kernel rather than by parser. Unrecognized names are therefore interpreted as a failed request rather than a parser error. Signed-off-by: Michal Kubecek --- ethtool.c | 1 + netlink/extapi.h | 2 ++ netlink/privflags.c | 51 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/ethtool.c b/ethtool.c index 843c710eb408..81472ad40a5b 100644 --- a/ethtool.c +++ b/ethtool.c @@ -5383,6 +5383,7 @@ static const struct option args[] = { { .opts = "--set-priv-flags", .func = do_sprivflags, + .nlfunc = nl_sprivflags, .help = "Set private flags", .xhelp = " FLAG on|off ...\n" }, diff --git a/netlink/extapi.h b/netlink/extapi.h index 1bbe3fc21271..ec5d086f05df 100644 --- a/netlink/extapi.h +++ b/netlink/extapi.h @@ -23,6 +23,7 @@ int nl_permaddr(struct cmd_context *ctx); int nl_gfeatures(struct cmd_context *ctx); int nl_sfeatures(struct cmd_context *ctx); int nl_gprivflags(struct cmd_context *ctx); +int nl_sprivflags(struct cmd_context *ctx); int nl_monitor(struct cmd_context *ctx); void nl_monitor_usage(void); @@ -50,6 +51,7 @@ static inline void nl_monitor_usage(void) #define nl_gfeatures NULL #define nl_sfeatures NULL #define nl_gprivflags NULL +#define nl_sprivflags NULL #endif /* ETHTOOL_ENABLE_NETLINK */ diff --git a/netlink/privflags.c b/netlink/privflags.c index b552c21ed191..a06cd6d88d9d 100644 --- a/netlink/privflags.c +++ b/netlink/privflags.c @@ -1,7 +1,8 @@ /* * privflags.c - netlink implementation of private flags commands * - * Implementation of "ethtool --show-priv-flags " + * Implementation of "ethtool --show-priv-flags " and + * "ethtool --set-priv-flags ..." */ #include @@ -13,6 +14,7 @@ #include "netlink.h" #include "strset.h" #include "bitset.h" +#include "parser.h" /* PRIVFLAGS_GET */ @@ -107,3 +109,50 @@ int nl_gprivflags(struct cmd_context *ctx) return ret; return nlsock_send_get_request(nlsk, privflags_reply_cb); } + +/* PRIVFLAGS_SET */ + +static const struct bitset_parser_data privflags_parser_data = { + .force_hex = false, + .no_mask = false, +}; + +int nl_sprivflags(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_PRIVFLAGS_SET, false)) + return -EOPNOTSUPP; + + nlctx->cmd = "--set-priv-flags"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_PRIVFLAGS_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_PRIVFLAGS_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parse_bitset(nlctx, ETHTOOL_A_PRIVFLAGS_FLAGS, + &privflags_parser_data, msgbuff, NULL); + if (ret < 0) + return -EINVAL; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 2; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 1; +} From patchwork Thu May 28 23:22:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 218272 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 10789C433DF for ; Thu, 28 May 2020 23:22:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E79782084C for ; Thu, 28 May 2020 23:22:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437548AbgE1XWS (ORCPT ); Thu, 28 May 2020 19:22:18 -0400 Received: from mx2.suse.de ([195.135.220.15]:49488 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437531AbgE1XWE (ORCPT ); Thu, 28 May 2020 19:22:04 -0400 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 C7890AFF8; Thu, 28 May 2020 23:22:02 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id E8C76E32D2; Fri, 29 May 2020 01:22:02 +0200 (CEST) Message-Id: <6b8630102193ca84c9fcbde17b604aa22f9b14a3.1590707335.git.mkubecek@suse.cz> In-Reply-To: References: From: Michal Kubecek Subject: [PATCH ethtool 11/21] netlink: add netlink handler for gring (-g) To: John Linville , netdev@vger.kernel.org Cc: Andrew Lunn , Oleksij Rempel Date: Fri, 29 May 2020 01:22:02 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Implement "ethtool -g " subcommand using ETHTOOL_MSG_RINGS_GET netlink message. This retrieves and displays device ring sizes, traditionally provided by ETHTOOL_GRINGPARAM ioctl request. Also register the callback with monitor code so that the monitor can display ETHTOOL_MSG_RINGS_NTF notifications. Signed-off-by: Michal Kubecek --- Makefile.am | 2 +- ethtool.c | 1 + netlink/extapi.h | 2 ++ netlink/monitor.c | 8 ++++++ netlink/netlink.h | 13 +++++++++ netlink/rings.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 netlink/rings.c diff --git a/Makefile.am b/Makefile.am index 0a4c4e810c1c..f7d7b44a438d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,7 +31,7 @@ ethtool_SOURCES += \ netlink/monitor.c netlink/bitset.c netlink/bitset.h \ netlink/settings.c netlink/parser.c netlink/parser.h \ netlink/permaddr.c netlink/prettymsg.c netlink/prettymsg.h \ - netlink/features.c netlink/privflags.c \ + netlink/features.c netlink/privflags.c netlink/rings.c \ netlink/desc-ethtool.c netlink/desc-genlctrl.c \ netlink/desc-rtnl.c \ uapi/linux/ethtool_netlink.h \ diff --git a/ethtool.c b/ethtool.c index 81472ad40a5b..fc3fb11a6a19 100644 --- a/ethtool.c +++ b/ethtool.c @@ -5199,6 +5199,7 @@ static const struct option args[] = { { .opts = "-g|--show-ring", .func = do_gring, + .nlfunc = nl_gring, .help = "Query RX/TX ring parameters" }, { diff --git a/netlink/extapi.h b/netlink/extapi.h index ec5d086f05df..3b3579d53b59 100644 --- a/netlink/extapi.h +++ b/netlink/extapi.h @@ -24,6 +24,7 @@ int nl_gfeatures(struct cmd_context *ctx); int nl_sfeatures(struct cmd_context *ctx); int nl_gprivflags(struct cmd_context *ctx); int nl_sprivflags(struct cmd_context *ctx); +int nl_gring(struct cmd_context *ctx); int nl_monitor(struct cmd_context *ctx); void nl_monitor_usage(void); @@ -52,6 +53,7 @@ static inline void nl_monitor_usage(void) #define nl_sfeatures NULL #define nl_gprivflags NULL #define nl_sprivflags NULL +#define nl_gring NULL #endif /* ETHTOOL_ENABLE_NETLINK */ diff --git a/netlink/monitor.c b/netlink/monitor.c index ca2654bad71f..c89e6138dbec 100644 --- a/netlink/monitor.c +++ b/netlink/monitor.c @@ -39,6 +39,10 @@ static struct { .cmd = ETHTOOL_MSG_PRIVFLAGS_NTF, .cb = privflags_reply_cb, }, + { + .cmd = ETHTOOL_MSG_RINGS_NTF, + .cb = rings_reply_cb, + }, }; static void clear_filter(struct nl_context *nlctx) @@ -118,6 +122,10 @@ static struct monitor_option monitor_opts[] = { .pattern = "--show-priv-flags|--set-priv-flags", .cmd = ETHTOOL_MSG_PRIVFLAGS_NTF, }, + { + .pattern = "-g|--show-ring|-G|--set-ring", + .cmd = ETHTOOL_MSG_RINGS_NTF, + }, }; static bool pattern_match(const char *s, const char *pattern) diff --git a/netlink/netlink.h b/netlink/netlink.h index 2e90dbe095c9..fe68e23cccb3 100644 --- a/netlink/netlink.h +++ b/netlink/netlink.h @@ -64,6 +64,19 @@ int wol_reply_cb(const struct nlmsghdr *nlhdr, void *data); int debug_reply_cb(const struct nlmsghdr *nlhdr, void *data); int features_reply_cb(const struct nlmsghdr *nlhdr, void *data); int privflags_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int rings_reply_cb(const struct nlmsghdr *nlhdr, void *data); + +/* dump helpers */ + +static inline void show_u32(const struct nlattr *attr, const char *label) +{ + if (attr) + printf("%s%u\n", label, mnl_attr_get_u32(attr)); + else + printf("%sn/a\n", label); +} + +/* misc */ static inline void copy_devname(char *dst, const char *src) { diff --git a/netlink/rings.c b/netlink/rings.c new file mode 100644 index 000000000000..98ee5dbedb17 --- /dev/null +++ b/netlink/rings.c @@ -0,0 +1,71 @@ +/* + * rings.c - netlink implementation of ring commands + * + * Implementation of "ethtool -g " + */ + +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" + +/* RINGS_GET */ + +int rings_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_RINGS_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_RINGS_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (silent) + putchar('\n'); + printf("Ring parameters for %s:\n", nlctx->devname); + printf("Pre-set maximums:\n"); + show_u32(tb[ETHTOOL_A_RINGS_RX_MAX], "RX:\t\t"); + show_u32(tb[ETHTOOL_A_RINGS_RX_MINI_MAX], "RX Mini:\t"); + show_u32(tb[ETHTOOL_A_RINGS_RX_JUMBO_MAX], "RX Jumbo:\t"); + show_u32(tb[ETHTOOL_A_RINGS_TX_MAX], "TX:\t\t"); + printf("Current hardware settings:\n"); + show_u32(tb[ETHTOOL_A_RINGS_RX], "RX:\t\t"); + show_u32(tb[ETHTOOL_A_RINGS_RX_MINI], "RX Mini:\t"); + show_u32(tb[ETHTOOL_A_RINGS_RX_JUMBO], "RX Jumbo:\t"); + show_u32(tb[ETHTOOL_A_RINGS_TX], "TX:\t\t"); + + return MNL_CB_OK; +} + +int nl_gring(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_RINGS_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_RINGS_GET, + ETHTOOL_A_RINGS_HEADER, 0); + if (ret < 0) + return ret; + return nlsock_send_get_request(nlsk, rings_reply_cb); +} From patchwork Thu May 28 23:22:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 218271 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A29ECC433E0 for ; Thu, 28 May 2020 23:22:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8067720721 for ; Thu, 28 May 2020 23:22:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437559AbgE1XW3 (ORCPT ); Thu, 28 May 2020 19:22:29 -0400 Received: from mx2.suse.de ([195.135.220.15]:49688 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437549AbgE1XWU (ORCPT ); Thu, 28 May 2020 19:22:20 -0400 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 DB644AFFD; Thu, 28 May 2020 23:22:17 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id 0971AE32D2; Fri, 29 May 2020 01:22:18 +0200 (CEST) Message-Id: <73e17a306b77678442f108e49c941576211ff7e4.1590707335.git.mkubecek@suse.cz> In-Reply-To: References: From: Michal Kubecek Subject: [PATCH ethtool 14/21] netlink: add netlink handler for schannels (-L) To: John Linville , netdev@vger.kernel.org Cc: Andrew Lunn , Oleksij Rempel Date: Fri, 29 May 2020 01:22:18 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Implement "ethtool -L ..." subcommand to set network device channel counts using ETHTOOL_MSG_CHANNELS_SET netlink message. These are traditionally set using ETHTOOL_SCHANNELS ioctl request. Signed-off-by: Michal Kubecek --- ethtool.c | 1 + netlink/channels.c | 72 +++++++++++++++++++++++++++++++++++++++++++++- netlink/extapi.h | 2 ++ 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/ethtool.c b/ethtool.c index eff97f4dfe70..cf888e08b5a4 100644 --- a/ethtool.c +++ b/ethtool.c @@ -5371,6 +5371,7 @@ static const struct option args[] = { { .opts = "-L|--set-channels", .func = do_schannels, + .nlfunc = nl_schannels, .help = "Set Channels", .xhelp = " [ rx N ]\n" " [ tx N ]\n" diff --git a/netlink/channels.c b/netlink/channels.c index ddea17b4d670..c6002ceeb121 100644 --- a/netlink/channels.c +++ b/netlink/channels.c @@ -1,7 +1,7 @@ /* * channels.c - netlink implementation of channel commands * - * Implementation of "ethtool -l " + * Implementation of "ethtool -l " and "ethtool -L ..." */ #include @@ -11,6 +11,7 @@ #include "../internal.h" #include "../common.h" #include "netlink.h" +#include "parser.h" /* CHANNELS_GET */ @@ -69,3 +70,72 @@ int nl_gchannels(struct cmd_context *ctx) return ret; return nlsock_send_get_request(nlsk, channels_reply_cb); } + +/* CHANNELS_SET */ + +static const struct param_parser schannels_params[] = { + { + .arg = "rx", + .type = ETHTOOL_A_CHANNELS_RX_COUNT, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx", + .type = ETHTOOL_A_CHANNELS_TX_COUNT, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "other", + .type = ETHTOOL_A_CHANNELS_OTHER_COUNT, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "combined", + .type = ETHTOOL_A_CHANNELS_COMBINED_COUNT, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + {} +}; + +int nl_schannels(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_CHANNELS_SET, false)) + return -EOPNOTSUPP; + + nlctx->cmd = "-L"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_CHANNELS_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_CHANNELS_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, schannels_params, NULL, PARSER_GROUP_NONE); + if (ret < 0) + return 1; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 1; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 1; +} diff --git a/netlink/extapi.h b/netlink/extapi.h index 9438dcd3aa0f..9cea57ac040a 100644 --- a/netlink/extapi.h +++ b/netlink/extapi.h @@ -27,6 +27,7 @@ int nl_sprivflags(struct cmd_context *ctx); int nl_gring(struct cmd_context *ctx); int nl_sring(struct cmd_context *ctx); int nl_gchannels(struct cmd_context *ctx); +int nl_schannels(struct cmd_context *ctx); int nl_monitor(struct cmd_context *ctx); void nl_monitor_usage(void); @@ -58,6 +59,7 @@ static inline void nl_monitor_usage(void) #define nl_gring NULL #define nl_sring NULL #define nl_gchannels NULL +#define nl_schannels NULL #endif /* ETHTOOL_ENABLE_NETLINK */ From patchwork Thu May 28 23:22:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 218270 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 969A3C433DF for ; Thu, 28 May 2020 23:22:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7F9192084C for ; Thu, 28 May 2020 23:22:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437568AbgE1XWi (ORCPT ); Thu, 28 May 2020 19:22:38 -0400 Received: from mx2.suse.de ([195.135.220.15]:49792 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437558AbgE1XWa (ORCPT ); Thu, 28 May 2020 19:22:30 -0400 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 EB34DAFF7; Thu, 28 May 2020 23:22:27 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id 182EAE32D2; Fri, 29 May 2020 01:22:28 +0200 (CEST) Message-Id: In-Reply-To: References: From: Michal Kubecek Subject: [PATCH ethtool 16/21] netlink: add netlink handler for scoalesce (-C) To: John Linville , netdev@vger.kernel.org Cc: Andrew Lunn , Oleksij Rempel Date: Fri, 29 May 2020 01:22:28 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Implement "ethtool -C ..." subcommand to set network device coalescing parameters using ETHTOOL_MSG_COALESCE_SET netlink message. These are traditionally set using ETHTOOL_SCOALESCE ioctl request. Signed-off-by: Michal Kubecek --- ethtool.c | 1 + netlink/coalesce.c | 180 ++++++++++++++++++++++++++++++++++++++++++++- netlink/extapi.h | 2 + 3 files changed, 182 insertions(+), 1 deletion(-) diff --git a/ethtool.c b/ethtool.c index 97280cb676db..6a28307004d5 100644 --- a/ethtool.c +++ b/ethtool.c @@ -5173,6 +5173,7 @@ static const struct option args[] = { { .opts = "-C|--coalesce", .func = do_scoalesce, + .nlfunc = nl_scoalesce, .help = "Set coalesce options", .xhelp = " [adaptive-rx on|off]\n" " [adaptive-tx on|off]\n" diff --git a/netlink/coalesce.c b/netlink/coalesce.c index f1ad671c3bd4..65f75cf9a8dd 100644 --- a/netlink/coalesce.c +++ b/netlink/coalesce.c @@ -1,7 +1,7 @@ /* * coalesce.c - netlink implementation of coalescing commands * - * Implementation of "ethtool -c " + * Implementation of "ethtool -c " and "ethtool -C ..." */ #include @@ -11,6 +11,7 @@ #include "../internal.h" #include "../common.h" #include "netlink.h" +#include "parser.h" /* COALESCE_GET */ @@ -89,3 +90,180 @@ int nl_gcoalesce(struct cmd_context *ctx) return ret; return nlsock_send_get_request(nlsk, coalesce_reply_cb); } + +/* COALESCE_SET */ + +static const struct param_parser scoalesce_params[] = { + { + .arg = "adaptive-rx", + .type = ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "adaptive-tx", + .type = ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "sample-interval", + .type = ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "stats-block-usecs", + .type = ETHTOOL_A_COALESCE_STATS_BLOCK_USECS, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "pkt-rate-low", + .type = ETHTOOL_A_COALESCE_PKT_RATE_LOW, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "pkt-rate-high", + .type = ETHTOOL_A_COALESCE_PKT_RATE_HIGH, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-usecs", + .type = ETHTOOL_A_COALESCE_RX_USECS, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-frames", + .type = ETHTOOL_A_COALESCE_RX_MAX_FRAMES, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-usecs-irq", + .type = ETHTOOL_A_COALESCE_RX_USECS_IRQ, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-frames-irq", + .type = ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-usecs", + .type = ETHTOOL_A_COALESCE_TX_USECS, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-frames", + .type = ETHTOOL_A_COALESCE_TX_MAX_FRAMES, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-usecs-irq", + .type = ETHTOOL_A_COALESCE_TX_USECS_IRQ, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-frames-irq", + .type = ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-usecs-low", + .type = ETHTOOL_A_COALESCE_RX_USECS_LOW, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-frames-low", + .type = ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-usecs-low", + .type = ETHTOOL_A_COALESCE_TX_USECS_LOW, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-frames-low", + .type = ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-usecs-high", + .type = ETHTOOL_A_COALESCE_RX_USECS_HIGH, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "rx-frames-high", + .type = ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-usecs-high", + .type = ETHTOOL_A_COALESCE_TX_USECS_HIGH, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "tx-frames-high", + .type = ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + {} +}; + +int nl_scoalesce(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_COALESCE_SET, false)) + return -EOPNOTSUPP; + + nlctx->cmd = "-C"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_COALESCE_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_COALESCE_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, scoalesce_params, NULL, PARSER_GROUP_NONE); + if (ret < 0) + return 1; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 1; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 1; +} diff --git a/netlink/extapi.h b/netlink/extapi.h index f25fc6e4389f..d35029576d5c 100644 --- a/netlink/extapi.h +++ b/netlink/extapi.h @@ -29,6 +29,7 @@ int nl_sring(struct cmd_context *ctx); int nl_gchannels(struct cmd_context *ctx); int nl_schannels(struct cmd_context *ctx); int nl_gcoalesce(struct cmd_context *ctx); +int nl_scoalesce(struct cmd_context *ctx); int nl_monitor(struct cmd_context *ctx); void nl_monitor_usage(void); @@ -62,6 +63,7 @@ static inline void nl_monitor_usage(void) #define nl_gchannels NULL #define nl_schannels NULL #define nl_gcoalesce NULL +#define nl_scoalesce NULL #endif /* ETHTOOL_ENABLE_NETLINK */ From patchwork Thu May 28 23:22:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 218269 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 13E02C433E0 for ; Thu, 28 May 2020 23:22:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E860F20721 for ; Thu, 28 May 2020 23:22:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437573AbgE1XWm (ORCPT ); Thu, 28 May 2020 19:22:42 -0400 Received: from mx2.suse.de ([195.135.220.15]:49836 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437564AbgE1XWf (ORCPT ); Thu, 28 May 2020 19:22:35 -0400 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 F2606AFE5; Thu, 28 May 2020 23:22:32 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id 1F218E32D2; Fri, 29 May 2020 01:22:33 +0200 (CEST) Message-Id: <0d1220c934229cbf391f26400f09fa93d9eb9eb7.1590707335.git.mkubecek@suse.cz> In-Reply-To: References: From: Michal Kubecek Subject: [PATCH ethtool 17/21] netlink: add netlink handler for gpause (-a) To: John Linville , netdev@vger.kernel.org Cc: Andrew Lunn , Oleksij Rempel Date: Fri, 29 May 2020 01:22:33 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Implement "ethtool -a " subcommand using ETHTOOL_MSG_PAUSE_GET netlink message. This retrieves and diaplays device pause parameters, traditionally provided by ETHTOOL_GPAUSEPARAM ioctl request. Also register the callback with monitor code so that the monitor can display ETHTOOL_MSG_PAUSE_NTF notifications. When in monitor mode, negotiated status is not displayed. Signed-off-by: Michal Kubecek --- Makefile.am | 2 +- ethtool.c | 1 + netlink/extapi.h | 2 + netlink/monitor.c | 8 +++ netlink/netlink.h | 6 ++ netlink/pause.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 netlink/pause.c diff --git a/Makefile.am b/Makefile.am index 19cef636286f..5d6c4e9571d0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -32,7 +32,7 @@ ethtool_SOURCES += \ netlink/settings.c netlink/parser.c netlink/parser.h \ netlink/permaddr.c netlink/prettymsg.c netlink/prettymsg.h \ netlink/features.c netlink/privflags.c netlink/rings.c \ - netlink/channels.c netlink/coalesce.c \ + netlink/channels.c netlink/coalesce.c netlink/pause.c \ netlink/desc-ethtool.c netlink/desc-genlctrl.c \ netlink/desc-rtnl.c \ uapi/linux/ethtool_netlink.h \ diff --git a/ethtool.c b/ethtool.c index 6a28307004d5..b5b7ddab813d 100644 --- a/ethtool.c +++ b/ethtool.c @@ -5154,6 +5154,7 @@ static const struct option args[] = { { .opts = "-a|--show-pause", .func = do_gpause, + .nlfunc = nl_gpause, .help = "Show pause options" }, { diff --git a/netlink/extapi.h b/netlink/extapi.h index d35029576d5c..00ad74010d2c 100644 --- a/netlink/extapi.h +++ b/netlink/extapi.h @@ -30,6 +30,7 @@ int nl_gchannels(struct cmd_context *ctx); int nl_schannels(struct cmd_context *ctx); int nl_gcoalesce(struct cmd_context *ctx); int nl_scoalesce(struct cmd_context *ctx); +int nl_gpause(struct cmd_context *ctx); int nl_monitor(struct cmd_context *ctx); void nl_monitor_usage(void); @@ -64,6 +65,7 @@ static inline void nl_monitor_usage(void) #define nl_schannels NULL #define nl_gcoalesce NULL #define nl_scoalesce NULL +#define nl_gpause NULL #endif /* ETHTOOL_ENABLE_NETLINK */ diff --git a/netlink/monitor.c b/netlink/monitor.c index ef9cc7a6923a..f02b462ff102 100644 --- a/netlink/monitor.c +++ b/netlink/monitor.c @@ -51,6 +51,10 @@ static struct { .cmd = ETHTOOL_MSG_COALESCE_NTF, .cb = coalesce_reply_cb, }, + { + .cmd = ETHTOOL_MSG_PAUSE_NTF, + .cb = pause_reply_cb, + }, }; static void clear_filter(struct nl_context *nlctx) @@ -142,6 +146,10 @@ static struct monitor_option monitor_opts[] = { .pattern = "-c|--show-coalesce|-C|--coalesce", .cmd = ETHTOOL_MSG_COALESCE_NTF, }, + { + .pattern = "-a|--show-pause|-A|--pause", + .cmd = ETHTOOL_MSG_PAUSE_NTF, + }, }; static bool pattern_match(const char *s, const char *pattern) diff --git a/netlink/netlink.h b/netlink/netlink.h index d35048583f5e..7cbb23733f88 100644 --- a/netlink/netlink.h +++ b/netlink/netlink.h @@ -67,6 +67,7 @@ int privflags_reply_cb(const struct nlmsghdr *nlhdr, void *data); int rings_reply_cb(const struct nlmsghdr *nlhdr, void *data); int channels_reply_cb(const struct nlmsghdr *nlhdr, void *data); int coalesce_reply_cb(const struct nlmsghdr *nlhdr, void *data); +int pause_reply_cb(const struct nlmsghdr *nlhdr, void *data); /* dump helpers */ @@ -86,6 +87,11 @@ static inline const char *u8_to_bool(const struct nlattr *attr) return "n/a"; } +static inline void show_bool(const struct nlattr *attr, const char *label) +{ + printf("%s%s\n", label, u8_to_bool(attr)); +} + /* misc */ static inline void copy_devname(char *dst, const char *src) diff --git a/netlink/pause.c b/netlink/pause.c new file mode 100644 index 000000000000..c9fdaeeaa0bc --- /dev/null +++ b/netlink/pause.c @@ -0,0 +1,158 @@ +/* + * pause.c - netlink implementation of pause commands + * + * Implementation of "ethtool -a " + */ + +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" +#include "bitset.h" + +/* PAUSE_GET */ + +struct pause_autoneg_status { + bool pause; + bool asym_pause; +}; + +static void pause_autoneg_walker(unsigned int idx, const char *name, bool val, + void *data) +{ + struct pause_autoneg_status *status = data; + + if (idx == ETHTOOL_LINK_MODE_Pause_BIT) + status->pause = val; + if (idx == ETHTOOL_LINK_MODE_Asym_Pause_BIT) + status->asym_pause = val; +} + +static int pause_autoneg_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_LINKMODES_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct pause_autoneg_status ours = {}; + struct pause_autoneg_status peer = {}; + struct nl_context *nlctx = data; + bool rx_status = false; + bool tx_status = false; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + + if (!tb[ETHTOOL_A_LINKMODES_OURS] || !tb[ETHTOOL_A_LINKMODES_PEER]) + return MNL_CB_OK; + ret = walk_bitset(tb[ETHTOOL_A_LINKMODES_OURS], NULL, + pause_autoneg_walker, &ours); + if (ret < 0) + return err_ret; + ret = walk_bitset(tb[ETHTOOL_A_LINKMODES_PEER], NULL, + pause_autoneg_walker, &peer); + if (ret < 0) + return err_ret; + + if (ours.pause && peer.pause) { + rx_status = true; + tx_status = true; + } else if (ours.asym_pause && peer.asym_pause) { + if (ours.pause) + rx_status = true; + else if (peer.pause) + tx_status = true; + } + printf("RX negotiated: %s\nTX negotiated: %s\n", + rx_status ? "on" : "off", tx_status ? "on" : "off"); + + return MNL_CB_OK; +} + +static int show_pause_autoneg_status(struct nl_context *nlctx) +{ + const char *saved_devname; + int ret; + + saved_devname = nlctx->ctx->devname; + nlctx->ctx->devname = nlctx->devname; + ret = netlink_init_ethnl2_socket(nlctx); + if (ret < 0) + goto out; + + ret = nlsock_prep_get_request(nlctx->ethnl2_socket, + ETHTOOL_MSG_LINKMODES_GET, + ETHTOOL_A_LINKMODES_HEADER, + ETHTOOL_FLAG_COMPACT_BITSETS); + if (ret < 0) + goto out; + ret = nlsock_send_get_request(nlctx->ethnl2_socket, pause_autoneg_cb); + +out: + nlctx->ctx->devname = saved_devname; + return ret; +} + +int pause_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_PAUSE_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + struct nl_context *nlctx = data; + bool silent; + int err_ret; + int ret; + + silent = nlctx->is_dump || nlctx->is_monitor; + err_ret = silent ? MNL_CB_OK : MNL_CB_ERROR; + ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info); + if (ret < 0) + return err_ret; + nlctx->devname = get_dev_name(tb[ETHTOOL_A_PAUSE_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (silent) + putchar('\n'); + printf("Pause parameters for %s:\n", nlctx->devname); + show_bool(tb[ETHTOOL_A_PAUSE_AUTONEG], "Autonegotiate:\t"); + show_bool(tb[ETHTOOL_A_PAUSE_RX], "RX:\t\t"); + show_bool(tb[ETHTOOL_A_PAUSE_TX], "TX:\t\t"); + if (!nlctx->is_monitor && tb[ETHTOOL_A_PAUSE_AUTONEG] && + mnl_attr_get_u8(tb[ETHTOOL_A_PAUSE_AUTONEG])) { + ret = show_pause_autoneg_status(nlctx); + if (ret < 0) + return err_ret; + } + if (!silent) + putchar('\n'); + + return MNL_CB_OK; +} + +int nl_gpause(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_PAUSE_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_PAUSE_GET, + ETHTOOL_A_PAUSE_HEADER, 0); + if (ret < 0) + return ret; + return nlsock_send_get_request(nlsk, pause_reply_cb); +} From patchwork Thu May 28 23:22:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 218268 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 657CBC433DF for ; Thu, 28 May 2020 23:22:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 467852084C for ; Thu, 28 May 2020 23:22:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437588AbgE1XW4 (ORCPT ); Thu, 28 May 2020 19:22:56 -0400 Received: from mx2.suse.de ([195.135.220.15]:49900 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437583AbgE1XWu (ORCPT ); Thu, 28 May 2020 19:22:50 -0400 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 3F871AFFB; Thu, 28 May 2020 23:22:48 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id 341C2E32D2; Fri, 29 May 2020 01:22:48 +0200 (CEST) Message-Id: In-Reply-To: References: From: Michal Kubecek Subject: [PATCH ethtool 20/21] netlink: add netlink handler for seee (--set-eee) To: John Linville , netdev@vger.kernel.org Cc: Andrew Lunn , Oleksij Rempel Date: Fri, 29 May 2020 01:22:48 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Implement "ethtool --set-eee ..." subcommand to set network device EEE settings using ETHTOOL_MSG_EEE_SET netlink message. These are traditionally set using ETHTOOL_SEEE ioctl request. Signed-off-by: Michal Kubecek --- ethtool.c | 1 + netlink/eee.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++- netlink/extapi.h | 2 ++ 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/ethtool.c b/ethtool.c index f4aaab58aa5b..3b81345d7120 100644 --- a/ethtool.c +++ b/ethtool.c @@ -5413,6 +5413,7 @@ static const struct option args[] = { { .opts = "--set-eee", .func = do_seee, + .nlfunc = nl_seee, .help = "Set EEE settings", .xhelp = " [ eee on|off ]\n" " [ advertise %x ]\n" diff --git a/netlink/eee.c b/netlink/eee.c index c9a9fcfba1f5..d3135b2094a4 100644 --- a/netlink/eee.c +++ b/netlink/eee.c @@ -1,7 +1,8 @@ /* * eee.c - netlink implementation of eee commands * - * Implementation of "ethtool --show-eee " + * Implementation of "ethtool --show-eee " and + * "ethtool --set-eee ..." */ #include @@ -12,6 +13,7 @@ #include "../common.h" #include "netlink.h" #include "bitset.h" +#include "parser.h" /* EEE_GET */ @@ -106,3 +108,82 @@ int nl_geee(struct cmd_context *ctx) return ret; return nlsock_send_get_request(nlsk, eee_reply_cb); } + +/* EEE_SET */ + +static const struct bitset_parser_data advertise_parser_data = { + .no_mask = false, + .force_hex = true, +}; + +static const struct param_parser seee_params[] = { + { + .arg = "advertise", + .type = ETHTOOL_A_EEE_MODES_OURS, + .handler = nl_parse_bitset, + .handler_data = &advertise_parser_data, + .min_argc = 1, + }, + { + .arg = "tx-lpi", + .type = ETHTOOL_A_EEE_TX_LPI_ENABLED, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + { + .arg = "tx-timer", + .type = ETHTOOL_A_EEE_TX_LPI_TIMER, + .handler = nl_parse_direct_u32, + .min_argc = 1, + }, + { + .arg = "eee", + .type = ETHTOOL_A_EEE_ENABLED, + .handler = nl_parse_u8bool, + .min_argc = 1, + }, + {} +}; + +int nl_seee(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_msg_buff *msgbuff; + struct nl_socket *nlsk; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_EEE_SET, false)) + return -EOPNOTSUPP; + if (!ctx->argc) { + fprintf(stderr, "ethtool (--set-eee): parameters missing\n"); + return 1; + } + + nlctx->cmd = "--set-eee"; + nlctx->argp = ctx->argp; + nlctx->argc = ctx->argc; + nlctx->devname = ctx->devname; + nlsk = nlctx->ethnl_socket; + msgbuff = &nlsk->msgbuff; + + ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_EEE_SET, + NLM_F_REQUEST | NLM_F_ACK); + if (ret < 0) + return 2; + if (ethnla_fill_header(msgbuff, ETHTOOL_A_EEE_HEADER, + ctx->devname, 0)) + return -EMSGSIZE; + + ret = nl_parser(nlctx, seee_params, NULL, PARSER_GROUP_NONE); + if (ret < 0) + return 1; + + ret = nlsock_sendmsg(nlsk, NULL); + if (ret < 0) + return 76; + ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx); + if (ret == 0) + return 0; + else + return nlctx->exit_code ?: 76; +} diff --git a/netlink/extapi.h b/netlink/extapi.h index f16dd5ed25b4..387787f61015 100644 --- a/netlink/extapi.h +++ b/netlink/extapi.h @@ -33,6 +33,7 @@ int nl_scoalesce(struct cmd_context *ctx); int nl_gpause(struct cmd_context *ctx); int nl_spause(struct cmd_context *ctx); int nl_geee(struct cmd_context *ctx); +int nl_seee(struct cmd_context *ctx); int nl_monitor(struct cmd_context *ctx); void nl_monitor_usage(void); @@ -70,6 +71,7 @@ static inline void nl_monitor_usage(void) #define nl_gpause NULL #define nl_spause NULL #define nl_geee NULL +#define nl_seee NULL #endif /* ETHTOOL_ENABLE_NETLINK */