mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 10:45:49 +00:00
net-sysfs: expose number of carrier on/off changes
This allows to monitor carrier on/off transitions and detect link flapping issues: - new /sys/class/net/X/carrier_changes - new rtnetlink IFLA_CARRIER_CHANGES (getlink) Tested: - grep . /sys/class/net/*/carrier_changes + ip link set dev X down/up + plug/unplug cable - updated iproute2: prints IFLA_CARRIER_CHANGES - iproute2 20121211-2 (debian): unchanged behavior Signed-off-by: David Decotigny <decot@googlers.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9c76a114bb
commit
2d3b479df4
@ -1308,6 +1308,9 @@ struct net_device {
|
||||
atomic_long_t rx_dropped;
|
||||
atomic_long_t tx_dropped;
|
||||
|
||||
/* Stats to monitor carrier on<->off transitions */
|
||||
atomic_t carrier_changes;
|
||||
|
||||
#ifdef CONFIG_WIRELESS_EXT
|
||||
/* List of functions to handle Wireless Extensions (instead of ioctl).
|
||||
* See <net/iw_handler.h> for details. Jean II */
|
||||
|
@ -144,6 +144,7 @@ enum {
|
||||
IFLA_NUM_RX_QUEUES,
|
||||
IFLA_CARRIER,
|
||||
IFLA_PHYS_PORT_ID,
|
||||
IFLA_CARRIER_CHANGES,
|
||||
__IFLA_MAX
|
||||
};
|
||||
|
||||
|
@ -253,6 +253,16 @@ static ssize_t operstate_show(struct device *dev,
|
||||
}
|
||||
static DEVICE_ATTR_RO(operstate);
|
||||
|
||||
static ssize_t carrier_changes_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct net_device *netdev = to_net_dev(dev);
|
||||
return sprintf(buf, fmt_dec,
|
||||
atomic_read(&netdev->carrier_changes));
|
||||
}
|
||||
static DEVICE_ATTR_RO(carrier_changes);
|
||||
|
||||
/* read-write attributes */
|
||||
|
||||
static int change_mtu(struct net_device *net, unsigned long new_mtu)
|
||||
@ -386,6 +396,7 @@ static struct attribute *net_class_attrs[] = {
|
||||
&dev_attr_duplex.attr,
|
||||
&dev_attr_dormant.attr,
|
||||
&dev_attr_operstate.attr,
|
||||
&dev_attr_carrier_changes.attr,
|
||||
&dev_attr_ifalias.attr,
|
||||
&dev_attr_carrier.attr,
|
||||
&dev_attr_mtu.attr,
|
||||
|
@ -822,6 +822,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
|
||||
+ nla_total_size(4) /* IFLA_NUM_RX_QUEUES */
|
||||
+ nla_total_size(1) /* IFLA_OPERSTATE */
|
||||
+ nla_total_size(1) /* IFLA_LINKMODE */
|
||||
+ nla_total_size(4) /* IFLA_CARRIER_CHANGES */
|
||||
+ nla_total_size(ext_filter_mask
|
||||
& RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
|
||||
+ rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
|
||||
@ -970,7 +971,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
|
||||
(dev->qdisc &&
|
||||
nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) ||
|
||||
(dev->ifalias &&
|
||||
nla_put_string(skb, IFLA_IFALIAS, dev->ifalias)))
|
||||
nla_put_string(skb, IFLA_IFALIAS, dev->ifalias)) ||
|
||||
nla_put_u32(skb, IFLA_CARRIER_CHANGES,
|
||||
atomic_read(&dev->carrier_changes)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (1) {
|
||||
@ -1147,6 +1150,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
|
||||
[IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
|
||||
[IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
|
||||
[IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
|
||||
[IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */
|
||||
};
|
||||
|
||||
static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
|
||||
|
@ -310,6 +310,7 @@ void netif_carrier_on(struct net_device *dev)
|
||||
if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) {
|
||||
if (dev->reg_state == NETREG_UNINITIALIZED)
|
||||
return;
|
||||
atomic_inc(&dev->carrier_changes);
|
||||
linkwatch_fire_event(dev);
|
||||
if (netif_running(dev))
|
||||
__netdev_watchdog_up(dev);
|
||||
@ -328,6 +329,7 @@ void netif_carrier_off(struct net_device *dev)
|
||||
if (!test_and_set_bit(__LINK_STATE_NOCARRIER, &dev->state)) {
|
||||
if (dev->reg_state == NETREG_UNINITIALIZED)
|
||||
return;
|
||||
atomic_inc(&dev->carrier_changes);
|
||||
linkwatch_fire_event(dev);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user