Commit 3d2b847f authored by Michal Kubecek's avatar Michal Kubecek Committed by David S. Miller
Browse files

ethtool: provide link state with LINKSTATE_GET request



Implement LINKSTATE_GET netlink request to get link state information.

At the moment, only link up flag as provided by ETHTOOL_GLINK ioctl command
is returned.

LINKSTATE_GET request can be used with NLM_F_DUMP (without device
identification) to request the information for all devices in current
network namespace providing the data.

Signed-off-by: default avatarMichal Kubecek <mkubecek@suse.cz>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1b1b1847
Loading
Loading
Loading
Loading
+32 −1
Original line number Original line Diff line number Diff line
@@ -184,6 +184,7 @@ Userspace to kernel:
  ``ETHTOOL_MSG_LINKINFO_SET``          set link settings
  ``ETHTOOL_MSG_LINKINFO_SET``          set link settings
  ``ETHTOOL_MSG_LINKMODES_GET``         get link modes info
  ``ETHTOOL_MSG_LINKMODES_GET``         get link modes info
  ``ETHTOOL_MSG_LINKMODES_SET``         set link modes info
  ``ETHTOOL_MSG_LINKMODES_SET``         set link modes info
  ``ETHTOOL_MSG_LINKSTATE_GET``         get link state
  ===================================== ================================
  ===================================== ================================


Kernel to userspace:
Kernel to userspace:
@@ -194,6 +195,7 @@ Kernel to userspace:
  ``ETHTOOL_MSG_LINKINFO_NTF``          link settings notification
  ``ETHTOOL_MSG_LINKINFO_NTF``          link settings notification
  ``ETHTOOL_MSG_LINKMODES_GET_REPLY``   link modes info
  ``ETHTOOL_MSG_LINKMODES_GET_REPLY``   link modes info
  ``ETHTOOL_MSG_LINKMODES_NTF``         link modes notification
  ``ETHTOOL_MSG_LINKMODES_NTF``         link modes notification
  ``ETHTOOL_MSG_LINKSTATE_GET_REPLY``   link state info
  ===================================== ================================
  ===================================== ================================


``GET`` requests are sent by userspace applications to retrieve device
``GET`` requests are sent by userspace applications to retrieve device
@@ -392,6 +394,35 @@ is supposed to allow requesting changes without knowing what exactly kernel
supports.
supports.




LINKSTATE_GET
=============

Requests link state information. At the moment, only link up/down flag (as
provided by ``ETHTOOL_GLINK`` ioctl command) is provided but some future
extensions are planned (e.g. link down reason). This request does not have any
attributes.

Request contents:

  ====================================  ======  ==========================
  ``ETHTOOL_A_LINKSTATE_HEADER``        nested  request header
  ====================================  ======  ==========================

Kernel response contents:

  ====================================  ======  ==========================
  ``ETHTOOL_A_LINKSTATE_HEADER``        nested  reply header
  ``ETHTOOL_A_LINKSTATE_LINK``          bool    link state (up/down)
  ====================================  ======  ==========================

For most NIC drivers, the value of ``ETHTOOL_A_LINKSTATE_LINK`` returns
carrier flag provided by ``netif_carrier_ok()`` but there are drivers which
define their own handler.

``LINKSTATE_GET`` allows dump requests (kernel returns reply messages for all
devices supporting the request).


Request translation
Request translation
===================
===================


@@ -413,7 +444,7 @@ have their netlink replacement yet.
  ``ETHTOOL_GMSGLVL``                 n/a
  ``ETHTOOL_GMSGLVL``                 n/a
  ``ETHTOOL_SMSGLVL``                 n/a
  ``ETHTOOL_SMSGLVL``                 n/a
  ``ETHTOOL_NWAY_RST``                n/a
  ``ETHTOOL_NWAY_RST``                n/a
  ``ETHTOOL_GLINK``                   n/a
  ``ETHTOOL_GLINK``                   ``ETHTOOL_MSG_LINKSTATE_GET``
  ``ETHTOOL_GEEPROM``                 n/a
  ``ETHTOOL_GEEPROM``                 n/a
  ``ETHTOOL_SEEPROM``                 n/a
  ``ETHTOOL_SEEPROM``                 n/a
  ``ETHTOOL_GCOALESCE``               n/a
  ``ETHTOOL_GCOALESCE``               n/a
+14 −0
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@ enum {
	ETHTOOL_MSG_LINKINFO_SET,
	ETHTOOL_MSG_LINKINFO_SET,
	ETHTOOL_MSG_LINKMODES_GET,
	ETHTOOL_MSG_LINKMODES_GET,
	ETHTOOL_MSG_LINKMODES_SET,
	ETHTOOL_MSG_LINKMODES_SET,
	ETHTOOL_MSG_LINKSTATE_GET,


	/* add new constants above here */
	/* add new constants above here */
	__ETHTOOL_MSG_USER_CNT,
	__ETHTOOL_MSG_USER_CNT,
@@ -33,6 +34,7 @@ enum {
	ETHTOOL_MSG_LINKINFO_NTF,
	ETHTOOL_MSG_LINKINFO_NTF,
	ETHTOOL_MSG_LINKMODES_GET_REPLY,
	ETHTOOL_MSG_LINKMODES_GET_REPLY,
	ETHTOOL_MSG_LINKMODES_NTF,
	ETHTOOL_MSG_LINKMODES_NTF,
	ETHTOOL_MSG_LINKSTATE_GET_REPLY,


	/* add new constants above here */
	/* add new constants above here */
	__ETHTOOL_MSG_KERNEL_CNT,
	__ETHTOOL_MSG_KERNEL_CNT,
@@ -181,6 +183,18 @@ enum {
	ETHTOOL_A_LINKMODES_MAX = __ETHTOOL_A_LINKMODES_CNT - 1
	ETHTOOL_A_LINKMODES_MAX = __ETHTOOL_A_LINKMODES_CNT - 1
};
};


/* LINKSTATE */

enum {
	ETHTOOL_A_LINKSTATE_UNSPEC,
	ETHTOOL_A_LINKSTATE_HEADER,		/* nest - _A_HEADER_* */
	ETHTOOL_A_LINKSTATE_LINK,		/* u8 */

	/* add new constants above here */
	__ETHTOOL_A_LINKSTATE_CNT,
	ETHTOOL_A_LINKSTATE_MAX = __ETHTOOL_A_LINKSTATE_CNT - 1
};

/* generic netlink info */
/* generic netlink info */
#define ETHTOOL_GENL_NAME "ethtool"
#define ETHTOOL_GENL_NAME "ethtool"
#define ETHTOOL_GENL_VERSION 1
#define ETHTOOL_GENL_VERSION 1
+2 −1
Original line number Original line Diff line number Diff line
@@ -4,4 +4,5 @@ obj-y += ioctl.o common.o


obj-$(CONFIG_ETHTOOL_NETLINK)	+= ethtool_nl.o
obj-$(CONFIG_ETHTOOL_NETLINK)	+= ethtool_nl.o


ethtool_nl-y	:= netlink.o bitset.o strset.o linkinfo.o linkmodes.o
ethtool_nl-y	:= netlink.o bitset.o strset.o linkinfo.o linkmodes.o \
		   linkstate.o
+8 −0
Original line number Original line Diff line number Diff line
@@ -217,3 +217,11 @@ convert_legacy_settings_to_link_ksettings(
		= legacy_settings->eth_tp_mdix_ctrl;
		= legacy_settings->eth_tp_mdix_ctrl;
	return retval;
	return retval;
}
}

int __ethtool_get_link(struct net_device *dev)
{
	if (!dev->ethtool_ops->get_link)
		return -EOPNOTSUPP;

	return netif_running(dev) && dev->ethtool_ops->get_link(dev);
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -3,6 +3,7 @@
#ifndef _ETHTOOL_COMMON_H
#ifndef _ETHTOOL_COMMON_H
#define _ETHTOOL_COMMON_H
#define _ETHTOOL_COMMON_H


#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/ethtool.h>


/* compose link mode index from speed, type and duplex */
/* compose link mode index from speed, type and duplex */
@@ -19,6 +20,8 @@ extern const char
phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN];
phy_tunable_strings[__ETHTOOL_PHY_TUNABLE_COUNT][ETH_GSTRING_LEN];
extern const char link_mode_names[][ETH_GSTRING_LEN];
extern const char link_mode_names[][ETH_GSTRING_LEN];


int __ethtool_get_link(struct net_device *dev);

bool convert_legacy_settings_to_link_ksettings(
bool convert_legacy_settings_to_link_ksettings(
	struct ethtool_link_ksettings *link_ksettings,
	struct ethtool_link_ksettings *link_ksettings,
	const struct ethtool_cmd *legacy_settings);
	const struct ethtool_cmd *legacy_settings);
Loading