From patchwork Wed Jan 3 14:29:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Chevallier X-Patchwork-Id: 13510126 X-Patchwork-Delegate: mkubecek+ethtool@suse.cz Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9B3341A70D; Wed, 3 Jan 2024 14:30:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="DiHKYcuf" Received: by mail.gandi.net (Postfix) with ESMTPSA id 6A56CFF811; Wed, 3 Jan 2024 14:29:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1704292198; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Xrrvgf56DSbik+ImPwBcdwGs/2/nrHPzHa+bYZSGqSg=; b=DiHKYcufYGwiku85jeTROTJZR8bNmw2Ictj6lblZgaNgnopqctfBL5KlijE4kpZoy6VMbL 6Hv+cqL3npKUeVK4Nk37Z77GQPZGvdSRhHJxaRXizdrKAV5ys7t2rAyamqHdftNS7BkG45 GD+2xu6CMqBAHPgAaBsSzdB7It6SOAFDMeNwoA4BYMKu/kqYhg/uRybtJWAWNHLOo0H0fu bkCVusofkNbcgK/TIJfPmlHa0h5mN716V75ACMbyOHgN4QVqdDAGqiMrwBATGMKxbqkkuT ECMr4I1jGCKcG97OUe5wL87kwF0J/f0i7jn5D1ALLhrHvbO/6Sdthinfd/uJhQ== From: Maxime Chevallier To: davem@davemloft.net, Michal Kubecek Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Russell King , linux-arm-kernel@lists.infradead.org, Christophe Leroy , Herve Codina , Florian Fainelli , Heiner Kallweit , Vladimir Oltean , =?utf-8?q?K=C3=B6ry_Maincent?= , Jesse Brandeburg , Jonathan Corbet , =?utf-8?q?Marek_Beh=C3=BAn?= , Piergiorgio Beruto , Oleksij Rempel , =?utf-8?q?Nicol=C3=B2_Veronese?= , Simon Horman Subject: [PATCH ethtool-next 1/3] update UAPI header copies Date: Wed, 3 Jan 2024 15:29:46 +0100 Message-ID: <20240103142950.235888-2-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240103142950.235888-1-maxime.chevallier@bootlin.com> References: <20240103142950.235888-1-maxime.chevallier@bootlin.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-Sasl: maxime.chevallier@bootlin.com X-Patchwork-Delegate: mkubecek+ethtool@suse.cz Update to kernel commit 8a48a2dc24f8. Signed-off-by: Maxime Chevallier --- uapi/linux/ethtool.h | 56 +++- uapi/linux/ethtool_netlink.h | 31 ++ uapi/linux/if_link.h | 529 +++++++++++++++++++++++++++++++++++ uapi/linux/stddef.h | 2 +- 4 files changed, 604 insertions(+), 14 deletions(-) diff --git a/uapi/linux/ethtool.h b/uapi/linux/ethtool.h index 1d0731b..de2cbc8 100644 --- a/uapi/linux/ethtool.h +++ b/uapi/linux/ethtool.h @@ -1264,6 +1264,8 @@ struct ethtool_rxfh_indir { * hardware hash key. * @hfunc: Defines the current RSS hash function used by HW (or to be set to). * Valid values are one of the %ETH_RSS_HASH_*. + * @input_xfrm: Defines how the input data is transformed. Valid values are one + * of %RXH_XFRM_*. * @rsvd8: Reserved for future use; see the note on reserved space. * @rsvd32: Reserved for future use; see the note on reserved space. * @rss_config: RX ring/queue index for each hash value i.e., indirection table @@ -1283,7 +1285,8 @@ struct ethtool_rxfh { __u32 indir_size; __u32 key_size; __u8 hfunc; - __u8 rsvd8[3]; + __u8 input_xfrm; + __u8 rsvd8[2]; __u32 rsvd32; __u32 rss_config[]; }; @@ -1990,6 +1993,14 @@ static __inline__ int ethtool_validate_duplex(__u8 duplex) #define WOL_MODE_COUNT 8 +/* RSS hash function data + * XOR the corresponding source and destination fields of each specified + * protocol. Both copies of the XOR'ed fields are fed into the RSS and RXHASH + * calculation. Note that this XORing reduces the input set entropy and could + * be exploited to reduce the RSS queue spread. + */ +#define RXH_XFRM_SYM_XOR (1 << 0) + /* L2-L4 network traffic flow types */ #define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */ #define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */ @@ -2126,18 +2137,6 @@ enum ethtool_reset_flags { * refused. For drivers: ignore this field (use kernel's * __ETHTOOL_LINK_MODE_MASK_NBITS instead), any change to it will * be overwritten by kernel. - * @supported: Bitmap with each bit meaning given by - * %ethtool_link_mode_bit_indices for the link modes, physical - * connectors and other link features for which the interface - * supports autonegotiation or auto-detection. Read-only. - * @advertising: Bitmap with each bit meaning given by - * %ethtool_link_mode_bit_indices for the link modes, physical - * connectors and other link features that are advertised through - * autonegotiation or enabled for auto-detection. - * @lp_advertising: Bitmap with each bit meaning given by - * %ethtool_link_mode_bit_indices for the link modes, and other - * link features that the link partner advertised through - * autonegotiation; 0 if unknown or not applicable. Read-only. * @transceiver: Used to distinguish different possible PHY types, * reported consistently by PHYLIB. Read-only. * @master_slave_cfg: Master/slave port mode. @@ -2179,6 +2178,21 @@ enum ethtool_reset_flags { * %set_link_ksettings() should validate all fields other than @cmd * and @link_mode_masks_nwords that are not described as read-only or * deprecated, and must ignore all fields described as read-only. + * + * @link_mode_masks is divided into three bitfields, each of length + * @link_mode_masks_nwords: + * - supported: Bitmap with each bit meaning given by + * %ethtool_link_mode_bit_indices for the link modes, physical + * connectors and other link features for which the interface + * supports autonegotiation or auto-detection. Read-only. + * - advertising: Bitmap with each bit meaning given by + * %ethtool_link_mode_bit_indices for the link modes, physical + * connectors and other link features that are advertised through + * autonegotiation or enabled for auto-detection. + * - lp_advertising: Bitmap with each bit meaning given by + * %ethtool_link_mode_bit_indices for the link modes, and other + * link features that the link partner advertised through + * autonegotiation; 0 if unknown or not applicable. Read-only. */ struct ethtool_link_settings { __u32 cmd; @@ -2203,4 +2217,20 @@ struct ethtool_link_settings { * __u32 map_lp_advertising[link_mode_masks_nwords]; */ }; + +/** + * enum phy_upstream - Represents the upstream component a given PHY device + * is connected to, as in what is on the other end of the MII bus. Most PHYs + * will be attached to an Ethernet MAC controller, but in some cases, there's + * an intermediate PHY used as a media-converter, which will driver another + * MII interface as its output. + * @PHY_UPSTREAM_MAC: Upstream component is a MAC (a switch port, + * or ethernet controller) + * @PHY_UPSTREAM_PHY: Upstream component is a PHY (likely a media converter) + */ +enum phy_upstream { + PHY_UPSTREAM_MAC, + PHY_UPSTREAM_PHY, +}; + #endif /* _LINUX_ETHTOOL_H */ diff --git a/uapi/linux/ethtool_netlink.h b/uapi/linux/ethtool_netlink.h index a8b0d79..e3f0f30 100644 --- a/uapi/linux/ethtool_netlink.h +++ b/uapi/linux/ethtool_netlink.h @@ -57,6 +57,7 @@ enum { ETHTOOL_MSG_PLCA_GET_STATUS, ETHTOOL_MSG_MM_GET, ETHTOOL_MSG_MM_SET, + ETHTOOL_MSG_PHY_GET, /* add new constants above here */ __ETHTOOL_MSG_USER_CNT, @@ -109,6 +110,8 @@ enum { ETHTOOL_MSG_PLCA_NTF, ETHTOOL_MSG_MM_GET_REPLY, ETHTOOL_MSG_MM_NTF, + ETHTOOL_MSG_PHY_GET_REPLY, + ETHTOOL_MSG_PHY_NTF, /* add new constants above here */ __ETHTOOL_MSG_KERNEL_CNT, @@ -133,6 +136,7 @@ enum { ETHTOOL_A_HEADER_DEV_INDEX, /* u32 */ ETHTOOL_A_HEADER_DEV_NAME, /* string */ ETHTOOL_A_HEADER_FLAGS, /* u32 - ETHTOOL_FLAG_* */ + ETHTOOL_A_HEADER_PHY_INDEX, /* u32 */ /* add new constants above here */ __ETHTOOL_A_HEADER_CNT, @@ -908,6 +912,7 @@ enum { ETHTOOL_A_RSS_HFUNC, /* u32 */ ETHTOOL_A_RSS_INDIR, /* binary */ ETHTOOL_A_RSS_HKEY, /* binary */ + ETHTOOL_A_RSS_INPUT_XFRM, /* u32 */ __ETHTOOL_A_RSS_CNT, ETHTOOL_A_RSS_MAX = (__ETHTOOL_A_RSS_CNT - 1), @@ -975,6 +980,32 @@ enum { ETHTOOL_A_MM_MAX = (__ETHTOOL_A_MM_CNT - 1) }; +enum { + ETHTOOL_A_PHY_UPSTREAM_UNSPEC, + ETHTOOL_A_PHY_UPSTREAM_INDEX, /* u32 */ + ETHTOOL_A_PHY_UPSTREAM_SFP_NAME, /* string */ + + /* add new constants above here */ + __ETHTOOL_A_PHY_UPSTREAM_CNT, + ETHTOOL_A_PHY_UPSTREAM_MAX = (__ETHTOOL_A_PHY_UPSTREAM_CNT - 1) +}; + +enum { + ETHTOOL_A_PHY_UNSPEC, + ETHTOOL_A_PHY_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PHY_INDEX, /* u32 */ + ETHTOOL_A_PHY_DRVNAME, /* string */ + ETHTOOL_A_PHY_NAME, /* string */ + ETHTOOL_A_PHY_UPSTREAM_TYPE, /* u8 */ + ETHTOOL_A_PHY_UPSTREAM, /* nest - _A_PHY_UPSTREAM_* */ + ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME, /* string */ + ETHTOOL_A_PHY_ID, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_PHY_CNT, + ETHTOOL_A_PHY_MAX = (__ETHTOOL_A_PHY_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 c146352..d17271f 100644 --- a/uapi/linux/if_link.h +++ b/uapi/linux/if_link.h @@ -459,6 +459,286 @@ enum in6_addr_gen_mode { /* Bridge section */ +/** + * DOC: Bridge enum definition + * + * Please *note* that the timer values in the following section are expected + * in clock_t format, which is seconds multiplied by USER_HZ (generally + * defined as 100). + * + * @IFLA_BR_FORWARD_DELAY + * The bridge forwarding delay is the time spent in LISTENING state + * (before moving to LEARNING) and in LEARNING state (before moving + * to FORWARDING). Only relevant if STP is enabled. + * + * The valid values are between (2 * USER_HZ) and (30 * USER_HZ). + * The default value is (15 * USER_HZ). + * + * @IFLA_BR_HELLO_TIME + * The time between hello packets sent by the bridge, when it is a root + * bridge or a designated bridge. Only relevant if STP is enabled. + * + * The valid values are between (1 * USER_HZ) and (10 * USER_HZ). + * The default value is (2 * USER_HZ). + * + * @IFLA_BR_MAX_AGE + * The hello packet timeout is the time until another bridge in the + * spanning tree is assumed to be dead, after reception of its last hello + * message. Only relevant if STP is enabled. + * + * The valid values are between (6 * USER_HZ) and (40 * USER_HZ). + * The default value is (20 * USER_HZ). + * + * @IFLA_BR_AGEING_TIME + * Configure the bridge's FDB entries aging time. It is the time a MAC + * address will be kept in the FDB after a packet has been received from + * that address. After this time has passed, entries are cleaned up. + * Allow values outside the 802.1 standard specification for special cases: + * + * * 0 - entry never ages (all permanent) + * * 1 - entry disappears (no persistence) + * + * The default value is (300 * USER_HZ). + * + * @IFLA_BR_STP_STATE + * Turn spanning tree protocol on (*IFLA_BR_STP_STATE* > 0) or off + * (*IFLA_BR_STP_STATE* == 0) for this bridge. + * + * The default value is 0 (disabled). + * + * @IFLA_BR_PRIORITY + * Set this bridge's spanning tree priority, used during STP root bridge + * election. + * + * The valid values are between 0 and 65535. + * + * @IFLA_BR_VLAN_FILTERING + * Turn VLAN filtering on (*IFLA_BR_VLAN_FILTERING* > 0) or off + * (*IFLA_BR_VLAN_FILTERING* == 0). When disabled, the bridge will not + * consider the VLAN tag when handling packets. + * + * The default value is 0 (disabled). + * + * @IFLA_BR_VLAN_PROTOCOL + * Set the protocol used for VLAN filtering. + * + * The valid values are 0x8100(802.1Q) or 0x88A8(802.1AD). The default value + * is 0x8100(802.1Q). + * + * @IFLA_BR_GROUP_FWD_MASK + * The group forwarding mask. This is the bitmask that is applied to + * decide whether to forward incoming frames destined to link-local + * addresses (of the form 01:80:C2:00:00:0X). + * + * The default value is 0, which means the bridge does not forward any + * link-local frames coming on this port. + * + * @IFLA_BR_ROOT_ID + * The bridge root id, read only. + * + * @IFLA_BR_BRIDGE_ID + * The bridge id, read only. + * + * @IFLA_BR_ROOT_PORT + * The bridge root port, read only. + * + * @IFLA_BR_ROOT_PATH_COST + * The bridge root path cost, read only. + * + * @IFLA_BR_TOPOLOGY_CHANGE + * The bridge topology change, read only. + * + * @IFLA_BR_TOPOLOGY_CHANGE_DETECTED + * The bridge topology change detected, read only. + * + * @IFLA_BR_HELLO_TIMER + * The bridge hello timer, read only. + * + * @IFLA_BR_TCN_TIMER + * The bridge tcn timer, read only. + * + * @IFLA_BR_TOPOLOGY_CHANGE_TIMER + * The bridge topology change timer, read only. + * + * @IFLA_BR_GC_TIMER + * The bridge gc timer, read only. + * + * @IFLA_BR_GROUP_ADDR + * Set the MAC address of the multicast group this bridge uses for STP. + * The address must be a link-local address in standard Ethernet MAC address + * format. It is an address of the form 01:80:C2:00:00:0X, with X in [0, 4..f]. + * + * The default value is 0. + * + * @IFLA_BR_FDB_FLUSH + * Flush bridge's fdb dynamic entries. + * + * @IFLA_BR_MCAST_ROUTER + * Set bridge's multicast router if IGMP snooping is enabled. + * The valid values are: + * + * * 0 - disabled. + * * 1 - automatic (queried). + * * 2 - permanently enabled. + * + * The default value is 1. + * + * @IFLA_BR_MCAST_SNOOPING + * Turn multicast snooping on (*IFLA_BR_MCAST_SNOOPING* > 0) or off + * (*IFLA_BR_MCAST_SNOOPING* == 0). + * + * The default value is 1. + * + * @IFLA_BR_MCAST_QUERY_USE_IFADDR + * If enabled use the bridge's own IP address as source address for IGMP + * queries (*IFLA_BR_MCAST_QUERY_USE_IFADDR* > 0) or the default of 0.0.0.0 + * (*IFLA_BR_MCAST_QUERY_USE_IFADDR* == 0). + * + * The default value is 0 (disabled). + * + * @IFLA_BR_MCAST_QUERIER + * Enable (*IFLA_BR_MULTICAST_QUERIER* > 0) or disable + * (*IFLA_BR_MULTICAST_QUERIER* == 0) IGMP querier, ie sending of multicast + * queries by the bridge. + * + * The default value is 0 (disabled). + * + * @IFLA_BR_MCAST_HASH_ELASTICITY + * Set multicast database hash elasticity, It is the maximum chain length in + * the multicast hash table. This attribute is *deprecated* and the value + * is always 16. + * + * @IFLA_BR_MCAST_HASH_MAX + * Set maximum size of the multicast hash table + * + * The default value is 4096, the value must be a power of 2. + * + * @IFLA_BR_MCAST_LAST_MEMBER_CNT + * The Last Member Query Count is the number of Group-Specific Queries + * sent before the router assumes there are no local members. The Last + * Member Query Count is also the number of Group-and-Source-Specific + * Queries sent before the router assumes there are no listeners for a + * particular source. + * + * The default value is 2. + * + * @IFLA_BR_MCAST_STARTUP_QUERY_CNT + * The Startup Query Count is the number of Queries sent out on startup, + * separated by the Startup Query Interval. + * + * The default value is 2. + * + * @IFLA_BR_MCAST_LAST_MEMBER_INTVL + * The Last Member Query Interval is the Max Response Time inserted into + * Group-Specific Queries sent in response to Leave Group messages, and + * is also the amount of time between Group-Specific Query messages. + * + * The default value is (1 * USER_HZ). + * + * @IFLA_BR_MCAST_MEMBERSHIP_INTVL + * The interval after which the bridge will leave a group, if no membership + * reports for this group are received. + * + * The default value is (260 * USER_HZ). + * + * @IFLA_BR_MCAST_QUERIER_INTVL + * The interval between queries sent by other routers. if no queries are + * seen after this delay has passed, the bridge will start to send its own + * queries (as if *IFLA_BR_MCAST_QUERIER_INTVL* was enabled). + * + * The default value is (255 * USER_HZ). + * + * @IFLA_BR_MCAST_QUERY_INTVL + * The Query Interval is the interval between General Queries sent by + * the Querier. + * + * The default value is (125 * USER_HZ). The minimum value is (1 * USER_HZ). + * + * @IFLA_BR_MCAST_QUERY_RESPONSE_INTVL + * The Max Response Time used to calculate the Max Resp Code inserted + * into the periodic General Queries. + * + * The default value is (10 * USER_HZ). + * + * @IFLA_BR_MCAST_STARTUP_QUERY_INTVL + * The interval between queries in the startup phase. + * + * The default value is (125 * USER_HZ) / 4. The minimum value is (1 * USER_HZ). + * + * @IFLA_BR_NF_CALL_IPTABLES + * Enable (*NF_CALL_IPTABLES* > 0) or disable (*NF_CALL_IPTABLES* == 0) + * iptables hooks on the bridge. + * + * The default value is 0 (disabled). + * + * @IFLA_BR_NF_CALL_IP6TABLES + * Enable (*NF_CALL_IP6TABLES* > 0) or disable (*NF_CALL_IP6TABLES* == 0) + * ip6tables hooks on the bridge. + * + * The default value is 0 (disabled). + * + * @IFLA_BR_NF_CALL_ARPTABLES + * Enable (*NF_CALL_ARPTABLES* > 0) or disable (*NF_CALL_ARPTABLES* == 0) + * arptables hooks on the bridge. + * + * The default value is 0 (disabled). + * + * @IFLA_BR_VLAN_DEFAULT_PVID + * VLAN ID applied to untagged and priority-tagged incoming packets. + * + * The default value is 1. Setting to the special value 0 makes all ports of + * this bridge not have a PVID by default, which means that they will + * not accept VLAN-untagged traffic. + * + * @IFLA_BR_PAD + * Bridge attribute padding type for netlink message. + * + * @IFLA_BR_VLAN_STATS_ENABLED + * Enable (*IFLA_BR_VLAN_STATS_ENABLED* == 1) or disable + * (*IFLA_BR_VLAN_STATS_ENABLED* == 0) per-VLAN stats accounting. + * + * The default value is 0 (disabled). + * + * @IFLA_BR_MCAST_STATS_ENABLED + * Enable (*IFLA_BR_MCAST_STATS_ENABLED* > 0) or disable + * (*IFLA_BR_MCAST_STATS_ENABLED* == 0) multicast (IGMP/MLD) stats + * accounting. + * + * The default value is 0 (disabled). + * + * @IFLA_BR_MCAST_IGMP_VERSION + * Set the IGMP version. + * + * The valid values are 2 and 3. The default value is 2. + * + * @IFLA_BR_MCAST_MLD_VERSION + * Set the MLD version. + * + * The valid values are 1 and 2. The default value is 1. + * + * @IFLA_BR_VLAN_STATS_PER_PORT + * Enable (*IFLA_BR_VLAN_STATS_PER_PORT* == 1) or disable + * (*IFLA_BR_VLAN_STATS_PER_PORT* == 0) per-VLAN per-port stats accounting. + * Can be changed only when there are no port VLANs configured. + * + * The default value is 0 (disabled). + * + * @IFLA_BR_MULTI_BOOLOPT + * The multi_boolopt is used to control new boolean options to avoid adding + * new netlink attributes. You can look at ``enum br_boolopt_id`` for those + * options. + * + * @IFLA_BR_MCAST_QUERIER_STATE + * Bridge mcast querier states, read only. + * + * @IFLA_BR_FDB_N_LEARNED + * The number of dynamically learned FDB entries for the current bridge, + * read only. + * + * @IFLA_BR_FDB_MAX_LEARNED + * Set the number of max dynamically learned FDB entries for the current + * bridge. + */ enum { IFLA_BR_UNSPEC, IFLA_BR_FORWARD_DELAY, @@ -520,11 +800,252 @@ struct ifla_bridge_id { __u8 addr[6]; /* ETH_ALEN */ }; +/** + * DOC: Bridge mode enum definition + * + * @BRIDGE_MODE_HAIRPIN + * Controls whether traffic may be sent back out of the port on which it + * was received. This option is also called reflective relay mode, and is + * used to support basic VEPA (Virtual Ethernet Port Aggregator) + * capabilities. By default, this flag is turned off and the bridge will + * not forward traffic back out of the receiving port. + */ enum { BRIDGE_MODE_UNSPEC, BRIDGE_MODE_HAIRPIN, }; +/** + * DOC: Bridge port enum definition + * + * @IFLA_BRPORT_STATE + * The operation state of the port. Here are the valid values. + * + * * 0 - port is in STP *DISABLED* state. Make this port completely + * inactive for STP. This is also called BPDU filter and could be used + * to disable STP on an untrusted port, like a leaf virtual device. + * The traffic forwarding is also stopped on this port. + * * 1 - port is in STP *LISTENING* state. Only valid if STP is enabled + * on the bridge. In this state the port listens for STP BPDUs and + * drops all other traffic frames. + * * 2 - port is in STP *LEARNING* state. Only valid if STP is enabled on + * the bridge. In this state the port will accept traffic only for the + * purpose of updating MAC address tables. + * * 3 - port is in STP *FORWARDING* state. Port is fully active. + * * 4 - port is in STP *BLOCKING* state. Only valid if STP is enabled on + * the bridge. This state is used during the STP election process. + * In this state, port will only process STP BPDUs. + * + * @IFLA_BRPORT_PRIORITY + * The STP port priority. The valid values are between 0 and 255. + * + * @IFLA_BRPORT_COST + * The STP path cost of the port. The valid values are between 1 and 65535. + * + * @IFLA_BRPORT_MODE + * Set the bridge port mode. See *BRIDGE_MODE_HAIRPIN* for more details. + * + * @IFLA_BRPORT_GUARD + * Controls whether STP BPDUs will be processed by the bridge port. By + * default, the flag is turned off to allow BPDU processing. Turning this + * flag on will disable the bridge port if a STP BPDU packet is received. + * + * If the bridge has Spanning Tree enabled, hostile devices on the network + * may send BPDU on a port and cause network failure. Setting *guard on* + * will detect and stop this by disabling the port. The port will be + * restarted if the link is brought down, or removed and reattached. + * + * @IFLA_BRPORT_PROTECT + * Controls whether a given port is allowed to become a root port or not. + * Only used when STP is enabled on the bridge. By default the flag is off. + * + * This feature is also called root port guard. If BPDU is received from a + * leaf (edge) port, it should not be elected as root port. This could + * be used if using STP on a bridge and the downstream bridges are not fully + * trusted; this prevents a hostile guest from rerouting traffic. + * + * @IFLA_BRPORT_FAST_LEAVE + * This flag allows the bridge to immediately stop multicast traffic + * forwarding on a port that receives an IGMP Leave message. It is only used + * when IGMP snooping is enabled on the bridge. By default the flag is off. + * + * @IFLA_BRPORT_LEARNING + * Controls whether a given port will learn *source* MAC addresses from + * received traffic or not. Also controls whether dynamic FDB entries + * (which can also be added by software) will be refreshed by incoming + * traffic. By default this flag is on. + * + * @IFLA_BRPORT_UNICAST_FLOOD + * Controls whether unicast traffic for which there is no FDB entry will + * be flooded towards this port. By default this flag is on. + * + * @IFLA_BRPORT_PROXYARP + * Enable proxy ARP on this port. + * + * @IFLA_BRPORT_LEARNING_SYNC + * Controls whether a given port will sync MAC addresses learned on device + * port to bridge FDB. + * + * @IFLA_BRPORT_PROXYARP_WIFI + * Enable proxy ARP on this port which meets extended requirements by + * IEEE 802.11 and Hotspot 2.0 specifications. + * + * @IFLA_BRPORT_ROOT_ID + * + * @IFLA_BRPORT_BRIDGE_ID + * + * @IFLA_BRPORT_DESIGNATED_PORT + * + * @IFLA_BRPORT_DESIGNATED_COST + * + * @IFLA_BRPORT_ID + * + * @IFLA_BRPORT_NO + * + * @IFLA_BRPORT_TOPOLOGY_CHANGE_ACK + * + * @IFLA_BRPORT_CONFIG_PENDING + * + * @IFLA_BRPORT_MESSAGE_AGE_TIMER + * + * @IFLA_BRPORT_FORWARD_DELAY_TIMER + * + * @IFLA_BRPORT_HOLD_TIMER + * + * @IFLA_BRPORT_FLUSH + * Flush bridge ports' fdb dynamic entries. + * + * @IFLA_BRPORT_MULTICAST_ROUTER + * Configure the port's multicast router presence. A port with + * a multicast router will receive all multicast traffic. + * The valid values are: + * + * * 0 disable multicast routers on this port + * * 1 let the system detect the presence of routers (default) + * * 2 permanently enable multicast traffic forwarding on this port + * * 3 enable multicast routers temporarily on this port, not depending + * on incoming queries. + * + * @IFLA_BRPORT_PAD + * + * @IFLA_BRPORT_MCAST_FLOOD + * Controls whether a given port will flood multicast traffic for which + * there is no MDB entry. By default this flag is on. + * + * @IFLA_BRPORT_MCAST_TO_UCAST + * Controls whether a given port will replicate packets using unicast + * instead of multicast. By default this flag is off. + * + * This is done by copying the packet per host and changing the multicast + * destination MAC to a unicast one accordingly. + * + * *mcast_to_unicast* works on top of the multicast snooping feature of the + * bridge. Which means unicast copies are only delivered to hosts which + * are interested in unicast and signaled this via IGMP/MLD reports previously. + * + * This feature is intended for interface types which have a more reliable + * and/or efficient way to deliver unicast packets than broadcast ones + * (e.g. WiFi). + * + * However, it should only be enabled on interfaces where no IGMPv2/MLDv1 + * report suppression takes place. IGMP/MLD report suppression issue is + * usually overcome by the network daemon (supplicant) enabling AP isolation + * and by that separating all STAs. + * + * Delivery of STA-to-STA IP multicast is made possible again by enabling + * and utilizing the bridge hairpin mode, which considers the incoming port + * as a potential outgoing port, too (see *BRIDGE_MODE_HAIRPIN* option). + * Hairpin mode is performed after multicast snooping, therefore leading + * to only deliver reports to STAs running a multicast router. + * + * @IFLA_BRPORT_VLAN_TUNNEL + * Controls whether vlan to tunnel mapping is enabled on the port. + * By default this flag is off. + * + * @IFLA_BRPORT_BCAST_FLOOD + * Controls flooding of broadcast traffic on the given port. By default + * this flag is on. + * + * @IFLA_BRPORT_GROUP_FWD_MASK + * Set the group forward mask. This is a bitmask that is applied to + * decide whether to forward incoming frames destined to link-local + * addresses. The addresses of the form are 01:80:C2:00:00:0X (defaults + * to 0, which means the bridge does not forward any link-local frames + * coming on this port). + * + * @IFLA_BRPORT_NEIGH_SUPPRESS + * Controls whether neighbor discovery (arp and nd) proxy and suppression + * is enabled on the port. By default this flag is off. + * + * @IFLA_BRPORT_ISOLATED + * Controls whether a given port will be isolated, which means it will be + * able to communicate with non-isolated ports only. By default this + * flag is off. + * + * @IFLA_BRPORT_BACKUP_PORT + * Set a backup port. If the port loses carrier all traffic will be + * redirected to the configured backup port. Set the value to 0 to disable + * it. + * + * @IFLA_BRPORT_MRP_RING_OPEN + * + * @IFLA_BRPORT_MRP_IN_OPEN + * + * @IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT + * The number of per-port EHT hosts limit. The default value is 512. + * Setting to 0 is not allowed. + * + * @IFLA_BRPORT_MCAST_EHT_HOSTS_CNT + * The current number of tracked hosts, read only. + * + * @IFLA_BRPORT_LOCKED + * Controls whether a port will be locked, meaning that hosts behind the + * port will not be able to communicate through the port unless an FDB + * entry with the unit's MAC address is in the FDB. The common use case is + * that hosts are allowed access through authentication with the IEEE 802.1X + * protocol or based on whitelists. By default this flag is off. + * + * Please note that secure 802.1X deployments should always use the + * *BR_BOOLOPT_NO_LL_LEARN* flag, to not permit the bridge to populate its + * FDB based on link-local (EAPOL) traffic received on the port. + * + * @IFLA_BRPORT_MAB + * Controls whether a port will use MAC Authentication Bypass (MAB), a + * technique through which select MAC addresses may be allowed on a locked + * port, without using 802.1X authentication. Packets with an unknown source + * MAC address generates a "locked" FDB entry on the incoming bridge port. + * The common use case is for user space to react to these bridge FDB + * notifications and optionally replace the locked FDB entry with a normal + * one, allowing traffic to pass for whitelisted MAC addresses. + * + * Setting this flag also requires *IFLA_BRPORT_LOCKED* and + * *IFLA_BRPORT_LEARNING*. *IFLA_BRPORT_LOCKED* ensures that unauthorized + * data packets are dropped, and *IFLA_BRPORT_LEARNING* allows the dynamic + * FDB entries installed by user space (as replacements for the locked FDB + * entries) to be refreshed and/or aged out. + * + * @IFLA_BRPORT_MCAST_N_GROUPS + * + * @IFLA_BRPORT_MCAST_MAX_GROUPS + * Sets the maximum number of MDB entries that can be registered for a + * given port. Attempts to register more MDB entries at the port than this + * limit allows will be rejected, whether they are done through netlink + * (e.g. the bridge tool), or IGMP or MLD membership reports. Setting a + * limit of 0 disables the limit. The default value is 0. + * + * @IFLA_BRPORT_NEIGH_VLAN_SUPPRESS + * Controls whether neighbor discovery (arp and nd) proxy and suppression is + * enabled for a given port. By default this flag is off. + * + * Note that this option only takes effect when *IFLA_BRPORT_NEIGH_SUPPRESS* + * is enabled for a given port. + * + * @IFLA_BRPORT_BACKUP_NHID + * The FDB nexthop object ID to attach to packets being redirected to a + * backup port that has VLAN tunnel mapping enabled (via the + * *IFLA_BRPORT_VLAN_TUNNEL* option). Setting a value of 0 (default) has + * the effect of not attaching any ID. + */ enum { IFLA_BRPORT_UNSPEC, IFLA_BRPORT_STATE, /* Spanning tree state */ @@ -854,6 +1375,7 @@ enum { IFLA_VXLAN_DF, IFLA_VXLAN_VNIFILTER, /* only applicable with COLLECT_METADATA mode */ IFLA_VXLAN_LOCALBYPASS, + IFLA_VXLAN_LABEL_POLICY, /* IPv6 flow label policy; ifla_vxlan_label_policy */ __IFLA_VXLAN_MAX }; #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) @@ -871,6 +1393,13 @@ enum ifla_vxlan_df { VXLAN_DF_MAX = __VXLAN_DF_END - 1, }; +enum ifla_vxlan_label_policy { + VXLAN_LABEL_FIXED = 0, + VXLAN_LABEL_INHERIT = 1, + __VXLAN_LABEL_END, + VXLAN_LABEL_MAX = __VXLAN_LABEL_END - 1, +}; + /* GENEVE section */ enum { IFLA_GENEVE_UNSPEC, diff --git a/uapi/linux/stddef.h b/uapi/linux/stddef.h index b3d4a9c..bf9749d 100644 --- a/uapi/linux/stddef.h +++ b/uapi/linux/stddef.h @@ -27,7 +27,7 @@ union { \ struct { MEMBERS } ATTRS; \ struct TAG { MEMBERS } ATTRS NAME; \ - } + } ATTRS #ifdef __cplusplus /* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */ From patchwork Wed Jan 3 14:29:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Chevallier X-Patchwork-Id: 13510127 X-Patchwork-Delegate: mkubecek+ethtool@suse.cz Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1B45F1A726; Wed, 3 Jan 2024 14:30:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="buCe7svu" Received: by mail.gandi.net (Postfix) with ESMTPSA id C96CEFF806; Wed, 3 Jan 2024 14:29:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1704292200; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=11pFkuDDUTbLupTgUFR2BnipK5D6jj0VQU5ibyq/SFk=; b=buCe7svu6Rh6Zxb5xgxjNhZbGWWhdqX1jk/FUlXleCr8BMnYSkoFOCY4PsHaP6NgZb93SK 3KS9jPAv8WyUDeh6LrYpWCTKEQa+snp/X0jJiiDeIvfUWt/VqKzkuEYAyr747YCFVexkTz OQSrKb+SZIrlY3frl8cnTQzzWxtncRi/PRzpzJBfUmPcjwIag4gOdNMeeNN5sSfPiJKf1T ysWzCU32KGX97GitdJPCnx0oV8du/m0q8QLAkjGKKKssAyTQyJr7E4I0zvMmfezREzFkD3 T/zZydmeazwqifEJsDvPuTH9E8sdyb+2vHNCe1CMb2dxf1X5uqNpomrUl7s9pw== From: Maxime Chevallier To: davem@davemloft.net, Michal Kubecek Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Russell King , linux-arm-kernel@lists.infradead.org, Christophe Leroy , Herve Codina , Florian Fainelli , Heiner Kallweit , Vladimir Oltean , =?utf-8?q?K=C3=B6ry_Maincent?= , Jesse Brandeburg , Jonathan Corbet , =?utf-8?q?Marek_Beh=C3=BAn?= , Piergiorgio Beruto , Oleksij Rempel , =?utf-8?q?Nicol=C3=B2_Veronese?= , Simon Horman Subject: [PATCH ethtool-next 2/3] ethtool: Allow passing a PHY index for phy-targetting commands Date: Wed, 3 Jan 2024 15:29:47 +0100 Message-ID: <20240103142950.235888-3-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240103142950.235888-1-maxime.chevallier@bootlin.com> References: <20240103142950.235888-1-maxime.chevallier@bootlin.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-Sasl: maxime.chevallier@bootlin.com X-Patchwork-Delegate: mkubecek+ethtool@suse.cz With the introduction of PHY topology and the ability to list PHYs, we can now target some netlink commands to specific PHYs. This is done by passing a PHY index as a request parameter in the netlink GET command. This is useful for PSE-PD, PLCA and Cable-testing operations when multiple PHYs are on the link (e.g. when a PHY is used as an SFP upstream controller, and when there's another PHY within the SFP module). Introduce a new, generic, option "--phy N" that can be used in conjunction with PHY-targetting commands to pass the PHY index for the targetted PHY. Signed-off-by: Maxime Chevallier --- ethtool.c | 25 ++++++++++++++++++++- internal.h | 1 + netlink/cable_test.c | 4 ++-- netlink/msgbuff.c | 52 ++++++++++++++++++++++++++++++++++---------- netlink/msgbuff.h | 3 +++ netlink/nlsock.c | 3 ++- netlink/plca.c | 4 ++-- netlink/pse-pd.c | 4 ++-- 8 files changed, 76 insertions(+), 20 deletions(-) diff --git a/ethtool.c b/ethtool.c index af51220..4c7c792 100644 --- a/ethtool.c +++ b/ethtool.c @@ -5640,6 +5640,7 @@ struct option { const char *opts; bool no_dev; bool json; + bool targets_phy; int (*func)(struct cmd_context *); nl_chk_t nlchk; nl_func_t nlfunc; @@ -6053,12 +6054,14 @@ static const struct option args[] = { }, { .opts = "--cable-test", + .targets_phy = true, .json = true, .nlfunc = nl_cable_test, .help = "Perform a cable test", }, { .opts = "--cable-test-tdr", + .targets_phy = true, .json = true, .nlfunc = nl_cable_test_tdr, .help = "Print cable test time domain reflectrometery data", @@ -6086,11 +6089,13 @@ static const struct option args[] = { }, { .opts = "--get-plca-cfg", + .targets_phy = true, .nlfunc = nl_plca_get_cfg, .help = "Get PLCA configuration", }, { .opts = "--set-plca-cfg", + .targets_phy = true, .nlfunc = nl_plca_set_cfg, .help = "Set PLCA configuration", .xhelp = " [ enable on|off ]\n" @@ -6102,6 +6107,7 @@ static const struct option args[] = { }, { .opts = "--get-plca-status", + .targets_phy = true, .nlfunc = nl_plca_get_status, .help = "Get PLCA status information", }, @@ -6123,12 +6129,14 @@ static const struct option args[] = { }, { .opts = "--show-pse", + .targets_phy = true, .json = true, .nlfunc = nl_gpse, .help = "Show settings for Power Sourcing Equipment", }, { .opts = "--set-pse", + .targets_phy = true, .nlfunc = nl_spse, .help = "Set Power Sourcing Equipment settings", .xhelp = " [ podl-pse-admin-control enable|disable ]\n" @@ -6157,7 +6165,8 @@ static int show_usage(struct cmd_context *ctx __maybe_unused) fprintf(stdout, "Usage:\n"); for (i = 0; args[i].opts; i++) { fputs(" ethtool [ FLAGS ] ", stdout); - fprintf(stdout, "%s %s\t%s\n", + fprintf(stdout, "%s%s %s\t%s\n", + args[i].targets_phy ? "[ --phy PHY ] " : "", args[i].opts, args[i].no_dev ? "\t" : "DEVNAME", args[i].help); @@ -6437,6 +6446,16 @@ int main(int argc, char **argp) argc -= 1; continue; } + if (*argp && !strcmp(*argp, "--phy")) { + char *eptr; + + ctx.phy_index = strtoul(argp[1], &eptr, 0); + if (!argp[1][0] || *eptr) + exit_bad_args(); + argp += 2; + argc -= 2; + continue; + } break; } if (*argp && !strcmp(*argp, "--monitor")) { @@ -6472,6 +6491,10 @@ int main(int argc, char **argp) } if (ctx.json && !args[k].json) exit_bad_args(); + + if (!args[k].targets_phy && ctx.phy_index) + exit_bad_args(); + ctx.argc = argc; ctx.argp = argp; netlink_run_handler(&ctx, args[k].nlchk, args[k].nlfunc, !args[k].func); diff --git a/internal.h b/internal.h index 4b994f5..afb8121 100644 --- a/internal.h +++ b/internal.h @@ -222,6 +222,7 @@ struct cmd_context { unsigned long debug; /* debugging mask */ bool json; /* Output JSON, if supported */ bool show_stats; /* include command-specific stats */ + uint32_t phy_index; /* the phy index this command targets */ #ifdef ETHTOOL_ENABLE_NETLINK struct nl_context *nlctx; /* netlink context (opaque) */ #endif diff --git a/netlink/cable_test.c b/netlink/cable_test.c index 9305a47..ba21c6c 100644 --- a/netlink/cable_test.c +++ b/netlink/cable_test.c @@ -572,8 +572,8 @@ int nl_cable_test_tdr(struct cmd_context *ctx) if (ret < 0) return 2; - if (ethnla_fill_header(msgbuff, ETHTOOL_A_CABLE_TEST_TDR_HEADER, - ctx->devname, 0)) + if (ethnla_fill_header_phy(msgbuff, ETHTOOL_A_CABLE_TEST_TDR_HEADER, + ctx->devname, ctx->phy_index, 0)) return -EMSGSIZE; ret = nl_parser(nlctx, tdr_params, NULL, PARSER_GROUP_NEST, NULL); diff --git a/netlink/msgbuff.c b/netlink/msgbuff.c index 216f5b9..9b307eb 100644 --- a/netlink/msgbuff.c +++ b/netlink/msgbuff.c @@ -138,17 +138,9 @@ struct nlattr *ethnla_nest_start(struct nl_msg_buff *msgbuff, uint16_t type) return NULL; } -/** - * ethnla_fill_header() - write standard ethtool request header to message - * @msgbuff: message buffer - * @type: attribute type for header nest - * @devname: device name (NULL to omit) - * @flags: request flags (omitted if 0) - * - * Return: pointer to the nest attribute or null of error - */ -bool ethnla_fill_header(struct nl_msg_buff *msgbuff, uint16_t type, - const char *devname, uint32_t flags) +static bool __ethnla_fill_header_phy(struct nl_msg_buff *msgbuff, uint16_t type, + const char *devname, uint32_t phy_index, + uint32_t flags) { struct nlattr *nest; @@ -159,7 +151,9 @@ bool ethnla_fill_header(struct nl_msg_buff *msgbuff, uint16_t type, if ((devname && ethnla_put_strz(msgbuff, ETHTOOL_A_HEADER_DEV_NAME, devname)) || (flags && - ethnla_put_u32(msgbuff, ETHTOOL_A_HEADER_FLAGS, flags))) + ethnla_put_u32(msgbuff, ETHTOOL_A_HEADER_FLAGS, flags)) || + (phy_index && + ethnla_put_u32(msgbuff, ETHTOOL_A_HEADER_PHY_INDEX, phy_index))) goto err; ethnla_nest_end(msgbuff, nest); @@ -170,6 +164,40 @@ err: return true; } +/** + * ethnla_fill_header() - write standard ethtool request header to message + * @msgbuff: message buffer + * @type: attribute type for header nest + * @devname: device name (NULL to omit) + * @flags: request flags (omitted if 0) + * + * Return: pointer to the nest attribute or null of error + */ +bool ethnla_fill_header(struct nl_msg_buff *msgbuff, uint16_t type, + const char *devname, uint32_t flags) +{ + return __ethnla_fill_header_phy(msgbuff, type, devname, 0, flags); +} + +/** + * ethnla_fill_header_phy() - write standard ethtool request header to message, + * targetting a device's phy + * @msgbuff: message buffer + * @type: attribute type for header nest + * @devname: device name (NULL to omit) + * @phy_index: phy index to target + * @flags: request flags (omitted if 0) + * + * Return: pointer to the nest attribute or null of error + */ +bool ethnla_fill_header_phy(struct nl_msg_buff *msgbuff, uint16_t type, + const char *devname, uint32_t phy_index, + uint32_t flags) +{ + return __ethnla_fill_header_phy(msgbuff, type, devname, phy_index, + flags); +} + /** * __msg_init() - init a genetlink message, fill netlink and genetlink header * @msgbuff: message buffer diff --git a/netlink/msgbuff.h b/netlink/msgbuff.h index 7d6731f..7df19fc 100644 --- a/netlink/msgbuff.h +++ b/netlink/msgbuff.h @@ -47,6 +47,9 @@ bool ethnla_put(struct nl_msg_buff *msgbuff, uint16_t type, size_t len, struct nlattr *ethnla_nest_start(struct nl_msg_buff *msgbuff, uint16_t type); bool ethnla_fill_header(struct nl_msg_buff *msgbuff, uint16_t type, const char *devname, uint32_t flags); +bool ethnla_fill_header_phy(struct nl_msg_buff *msgbuff, uint16_t type, + const char *devname, uint32_t phy_index, + uint32_t flags); /* length of current message */ static inline unsigned int msgbuff_len(const struct nl_msg_buff *msgbuff) diff --git a/netlink/nlsock.c b/netlink/nlsock.c index 0ec2738..0b873a3 100644 --- a/netlink/nlsock.c +++ b/netlink/nlsock.c @@ -291,7 +291,8 @@ int nlsock_prep_get_request(struct nl_socket *nlsk, unsigned int nlcmd, ret = msg_init(nlctx, &nlsk->msgbuff, nlcmd, nlm_flags); if (ret < 0) return ret; - if (ethnla_fill_header(&nlsk->msgbuff, hdr_attrtype, devname, flags)) + if (ethnla_fill_header_phy(&nlsk->msgbuff, hdr_attrtype, devname, + nlctx->ctx->phy_index, flags)) return -EMSGSIZE; return 0; diff --git a/netlink/plca.c b/netlink/plca.c index 7d61e3b..7dc30a3 100644 --- a/netlink/plca.c +++ b/netlink/plca.c @@ -211,8 +211,8 @@ int nl_plca_set_cfg(struct cmd_context *ctx) NLM_F_REQUEST | NLM_F_ACK); if (ret < 0) return 2; - if (ethnla_fill_header(msgbuff, ETHTOOL_A_PLCA_HEADER, - ctx->devname, 0)) + if (ethnla_fill_header_phy(msgbuff, ETHTOOL_A_PLCA_HEADER, + ctx->devname, ctx->phy_index, 0)) return -EMSGSIZE; ret = nl_parser(nlctx, set_plca_params, NULL, PARSER_GROUP_NONE, NULL); diff --git a/netlink/pse-pd.c b/netlink/pse-pd.c index d6faff8..5ee3a28 100644 --- a/netlink/pse-pd.c +++ b/netlink/pse-pd.c @@ -174,8 +174,8 @@ int nl_spse(struct cmd_context *ctx) NLM_F_REQUEST | NLM_F_ACK); if (ret < 0) return 2; - if (ethnla_fill_header(msgbuff, ETHTOOL_A_PSE_HEADER, - ctx->devname, 0)) + if (ethnla_fill_header_phy(msgbuff, ETHTOOL_A_PSE_HEADER, + ctx->devname, ctx->phy_index, 0)) return -EMSGSIZE; ret = nl_parser(nlctx, spse_params, NULL, PARSER_GROUP_NONE, NULL); From patchwork Wed Jan 3 14:29:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Chevallier X-Patchwork-Id: 13510128 X-Patchwork-Delegate: mkubecek+ethtool@suse.cz Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 620D81B26C; Wed, 3 Jan 2024 14:30:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="oX835lge" Received: by mail.gandi.net (Postfix) with ESMTPSA id 46AA3FF815; Wed, 3 Jan 2024 14:30:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1704292201; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Pe3P7wt/OwUcNmZVPqnsg3tJHeu05OH3jwhq110IVpk=; b=oX835lgeD2rmnAQrb0XQunLn7zN4iD4oeb11rh8Aze4bAcp6W0QwxMVR28p8MV8peL5WN0 uIAgsQS0mbqWwc7F2rIUdehxXXwDJQ/8Sfsj2v38h7Au385jLDDtDNW3oZmUzzCP+/G0Hz qOHXogDKW+Uv0E6QGL6Il/OWIIyirNl27UtMg5y9vzLakBv587IzolwO+f3jnyTqwOK2by iTs+qTzT6zra/W3dJF22S/ubtmDcLlhK3pJL2u8SLkntkmA+RcRbhXpjaGzd4CgK0nUxDE M67Rkk+xc+PekDwkXV5LCNhoLpOUk7XVmIf1KiAl23e8zzHebV4AJobPrRIHPg== From: Maxime Chevallier To: davem@davemloft.net, Michal Kubecek Cc: Maxime Chevallier , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, thomas.petazzoni@bootlin.com, Andrew Lunn , Jakub Kicinski , Eric Dumazet , Paolo Abeni , Russell King , linux-arm-kernel@lists.infradead.org, Christophe Leroy , Herve Codina , Florian Fainelli , Heiner Kallweit , Vladimir Oltean , =?utf-8?q?K=C3=B6ry_Maincent?= , Jesse Brandeburg , Jonathan Corbet , =?utf-8?q?Marek_Beh=C3=BAn?= , Piergiorgio Beruto , Oleksij Rempel , =?utf-8?q?Nicol=C3=B2_Veronese?= , Simon Horman Subject: [PATCH ethtool-next 3/3] ethtool: Introduce a command to list PHYs Date: Wed, 3 Jan 2024 15:29:48 +0100 Message-ID: <20240103142950.235888-4-maxime.chevallier@bootlin.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240103142950.235888-1-maxime.chevallier@bootlin.com> References: <20240103142950.235888-1-maxime.chevallier@bootlin.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-Sasl: maxime.chevallier@bootlin.com X-Patchwork-Delegate: mkubecek+ethtool@suse.cz It is now possible to list all Ethernet PHYs that are present behind a given interface, since the following linux commit : 63d5eaf35ac3 ("net: ethtool: Introduce a command to list PHYs on an interface") This command relies on the netlink DUMP command to list them, by allowing to pass an interface name/id as a parameter in the DUMP request to only list PHYs on one interface. Therefore, we introduce a new helper function to prepare a interface-filtered dump request (the filter can be empty, to perform an unfiltered dump), and then uses it to implement PHY enumeration through the --show-phys command. Signed-off-by: Maxime Chevallier --- Makefile.am | 1 + ethtool.c | 5 ++ netlink/extapi.h | 1 + netlink/nlsock.c | 24 ++++++++ netlink/nlsock.h | 2 + netlink/phy.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 172 insertions(+) create mode 100644 netlink/phy.c diff --git a/Makefile.am b/Makefile.am index b9e06ad..2434507 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,6 +48,7 @@ ethtool_SOURCES += \ netlink/desc-rtnl.c netlink/cable_test.c netlink/tunnels.c \ netlink/plca.c \ netlink/pse-pd.c \ + netlink/phy.c \ uapi/linux/ethtool_netlink.h \ uapi/linux/netlink.h uapi/linux/genetlink.h \ uapi/linux/rtnetlink.h uapi/linux/if_link.h \ diff --git a/ethtool.c b/ethtool.c index 4c7c792..b877f2e 100644 --- a/ethtool.c +++ b/ethtool.c @@ -6141,6 +6141,11 @@ static const struct option args[] = { .help = "Set Power Sourcing Equipment settings", .xhelp = " [ podl-pse-admin-control enable|disable ]\n" }, + { + .opts = "--show-phys", + .nlfunc = nl_get_phy, + .help = "List PHYs" + }, { .opts = "-h|--help", .no_dev = true, diff --git a/netlink/extapi.h b/netlink/extapi.h index e2d6b71..8f87f26 100644 --- a/netlink/extapi.h +++ b/netlink/extapi.h @@ -55,6 +55,7 @@ int nl_get_mm(struct cmd_context *ctx); int nl_set_mm(struct cmd_context *ctx); int nl_gpse(struct cmd_context *ctx); int nl_spse(struct cmd_context *ctx); +int nl_get_phy(struct cmd_context *ctx); void nl_monitor_usage(void); diff --git a/netlink/nlsock.c b/netlink/nlsock.c index 0b873a3..510fc63 100644 --- a/netlink/nlsock.c +++ b/netlink/nlsock.c @@ -298,6 +298,30 @@ int nlsock_prep_get_request(struct nl_socket *nlsk, unsigned int nlcmd, return 0; } +int nlsock_prep_filtered_dump_request(struct nl_socket *nlsk, + unsigned int nlcmd, uint16_t hdr_attrtype, + u32 flags) +{ + unsigned int nlm_flags = NLM_F_REQUEST | NLM_F_ACK; + struct nl_context *nlctx = nlsk->nlctx; + const char *devname = nlctx->ctx->devname; + int ret; + + nlctx->is_dump = true; + nlm_flags |= NLM_F_DUMP; + + if (devname && !strcmp(devname, WILDCARD_DEVNAME)) + devname = NULL; + + ret = msg_init(nlctx, &nlsk->msgbuff, nlcmd, nlm_flags); + if (ret < 0) + return ret; + if (ethnla_fill_header(&nlsk->msgbuff, hdr_attrtype, devname, flags)) + return -EMSGSIZE; + + return 0; +} + #ifndef TEST_ETHTOOL /** * nlsock_sendmsg() - send a netlink message to kernel diff --git a/netlink/nlsock.h b/netlink/nlsock.h index b015f86..6a72966 100644 --- a/netlink/nlsock.h +++ b/netlink/nlsock.h @@ -38,6 +38,8 @@ int nlsock_init(struct nl_context *nlctx, struct nl_socket **__nlsk, void nlsock_done(struct nl_socket *nlsk); int nlsock_prep_get_request(struct nl_socket *nlsk, unsigned int nlcmd, uint16_t hdr_attrtype, u32 flags); +int nlsock_prep_filtered_dump_request(struct nl_socket *nlsk, unsigned int nlcmd, + uint16_t hdr_attrtype, u32 flags); ssize_t nlsock_sendmsg(struct nl_socket *nlsk, struct nl_msg_buff *__msgbuff); int nlsock_send_get_request(struct nl_socket *nlsk, mnl_cb_t cb); int nlsock_process_reply(struct nl_socket *nlsk, mnl_cb_t reply_cb, void *data); diff --git a/netlink/phy.c b/netlink/phy.c new file mode 100644 index 0000000..c195cb9 --- /dev/null +++ b/netlink/phy.c @@ -0,0 +1,139 @@ +/* + * phy.c - List PHYs on an interface and their parameters + * + * Implementation of "ethtool --show-phys " + */ + +#include +#include +#include +#include + +#include "../internal.h" +#include "../common.h" +#include "netlink.h" + +/* PHY_GET / PHY_DUMP */ + +static const char * phy_upstream_type_to_str(uint8_t upstream_type) +{ + switch (upstream_type) { + case PHY_UPSTREAM_PHY: return "PHY"; + case PHY_UPSTREAM_MAC: return "MAC"; + default: return "Unknown"; + } +} + +static int phy_show_upstream(const struct nlattr *nest) +{ + const struct nlattr *tb[ETHTOOL_A_PHY_UPSTREAM_MAX + 1] = {}; + DECLARE_ATTR_TB_INFO(tb); + int ret; + + ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info); + if (ret < 0) + return ret; + + open_json_object("upstream"); + + if (tb[ETHTOOL_A_PHY_UPSTREAM_INDEX]) + show_u32("upstream_index", "Upstream PHY index: ", + tb[ETHTOOL_A_PHY_UPSTREAM_INDEX]); + + if (tb[ETHTOOL_A_PHY_UPSTREAM_SFP_NAME]) + print_string(PRINT_ANY, "upstream_sfp_name", "Upstream SFP name: %s\n", + mnl_attr_get_str(tb[ETHTOOL_A_PHY_UPSTREAM_SFP_NAME])); + + close_json_object(); + + return 0; +} + +int phy_reply_cb(const struct nlmsghdr *nlhdr, void *data) +{ + const struct nlattr *tb[ETHTOOL_A_PHY_MAX + 1] = {}; + struct nl_context *nlctx = data; + DECLARE_ATTR_TB_INFO(tb); + uint8_t upstream_type; + 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_PHY_HEADER]); + if (!dev_ok(nlctx)) + return err_ret; + + if (silent) + print_nl(); + + open_json_object(NULL); + + print_string(PRINT_ANY, "ifname", "PHY for %s:\n", nlctx->devname); + + show_u32("phy_index", "PHY index: ", tb[ETHTOOL_A_PHY_INDEX]); + + print_string(PRINT_ANY, "drvname", "Driver name: %s\n", + mnl_attr_get_str(tb[ETHTOOL_A_PHY_DRVNAME])); + + print_string(PRINT_ANY, "name", "PHY device name: %s\n", + mnl_attr_get_str(tb[ETHTOOL_A_PHY_NAME])); + + if (tb[ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME]) + print_string(PRINT_ANY, "downstream_sfp_name", + "Downstream SFP bus name: %s\n", + mnl_attr_get_str(tb[ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME])); + + show_u32("phy_id", "PHY id: ", tb[ETHTOOL_A_PHY_ID]); + + upstream_type = mnl_attr_get_u8(tb[ETHTOOL_A_PHY_UPSTREAM_TYPE]); + print_string(PRINT_ANY, "upstream_type", "Upstream type: %s\n", + phy_upstream_type_to_str(upstream_type)); + + if (tb[ETHTOOL_A_PHY_UPSTREAM]) { + err_ret = phy_show_upstream(tb[ETHTOOL_A_PHY_UPSTREAM]); + if (err_ret) + goto err; + } + + if (!silent) + print_nl(); + + close_json_object(); + + return MNL_CB_OK; + +err: + close_json_object(); + return err_ret; +} + +int nl_get_phy(struct cmd_context *ctx) +{ + struct nl_context *nlctx = ctx->nlctx; + struct nl_socket *nlsk = nlctx->ethnl_socket; + u32 flags; + int ret; + + if (netlink_cmd_check(ctx, ETHTOOL_MSG_PHY_GET, true)) + return -EOPNOTSUPP; + if (ctx->argc > 0) { + fprintf(stderr, "ethtool: unexpected parameter '%s'\n", + *ctx->argp); + return 1; + } + + ret = nlsock_prep_filtered_dump_request(nlsk, ETHTOOL_MSG_PHY_GET, + ETHTOOL_A_PHY_HEADER, flags); + if (ret) + return ret; + + new_json_obj(ctx->json); + ret = nlsock_send_get_request(nlsk, phy_reply_cb); + delete_json_obj(); + return ret; +}