您的位置:首页 > 其它

网卡statistics数据内核过程分析

2018-03-16 00:31 423 查看

简介

本文只讲述网卡的statistics数据注册和获取流程,典型的如:
/sys/class/net/eth0/statistics/rx_packets
/sys/class/net/eth0/statistics/tx_packets
/sys/class/net/eth0/statistics/rx_bytes
/sys/class/net/eth0/statistics/tx_bytes
/sys/class/net/eth0/statistics/rx_dropped
/sys/class/net/eth0/statistics/tx_dropped

或者通过# ifconfig eth0查看到的数据

设备节点的创建

注册

在网卡加入到kernel的时候都必须通过register_netdevice()进行注册,该函数通过调用netdev_register_kobject()函数来设置相关信息并注册对应的设备节点。
点击(此处)折叠或打开/* Create sysfs entries for network device. */ 

int netdev_register_kobject(struct net_device *ndev){ 

    struct device *dev = &(ndev->dev); 

    const struct attribute_group **groups = ndev->sysfs_groups; 

    ... 

    dev->groups = groups; 

    ... 

    *groups++ = &netstat_group; 

    ... 

    device_add(dev); 

}
device_add()->device_add_attrs()->device_add_groups(dev->groups)->sysfs_create_groups()

netstat_group定义

点击(此处)折叠或打开#define NETSTAT_ENTRY(name)                        \

static ssize_t name##_show(struct device *d,                \

             struct device_attribute *attr, char *buf)     \

{                                    \

    return netstat_show(d, attr, buf,                \

             offsetof(struct rtnl_link_stats64, name));    \

}                                    \

static DEVICE_ATTR_RO(name)

NETSTAT_ENTRY(rx_packets);

NETSTAT_ENTRY(tx_packets);

NETSTAT_ENTRY(rx_bytes);

NETSTAT_ENTRY(tx_bytes);

NETSTAT_ENTRY(rx_errors);

NETSTAT_ENTRY(tx_errors);

NETSTAT_ENTRY(rx_dropped);

NETSTAT_ENTRY(tx_dropped);

NETSTAT_ENTRY(multicast);

NETSTAT_ENTRY(collisions);

NETSTAT_ENTRY(rx_length_errors);

NETSTAT_ENTRY(rx_over_errors);

NETSTAT_ENTRY(rx_crc_errors);

NETSTAT_ENTRY(rx_frame_errors);

NETSTAT_ENTRY(rx_fifo_errors);

NETSTAT_ENTRY(rx_missed_errors);

NETSTAT_ENTRY(tx_aborted_errors);

NETSTAT_ENTRY(tx_carrier_errors);

NETSTAT_ENTRY(tx_fifo_errors);

NETSTAT_ENTRY(tx_heartbeat_errors);

NETSTAT_ENTRY(tx_window_errors);

NETSTAT_ENTRY(rx_compressed);

NETSTAT_ENTRY(tx_compressed);

NETSTAT_ENTRY(rx_nohandler);

static struct attribute *netstat_attrs[] = {

    &dev_attr_rx_packets.attr,

    &dev_attr_tx_packets.attr,

    &dev_attr_rx_bytes.attr,

    &dev_attr_tx_bytes.attr,

    &dev_attr_rx_errors.attr,

    &dev_attr_tx_errors.attr,

    &dev_attr_rx_dropped.attr,

    &dev_attr_tx_dropped.attr,

    &dev_attr_multicast.attr,

    &dev_attr_collisions.attr,

    &dev_attr_rx_length_errors.attr,

    &dev_attr_rx_over_errors.attr,

    &dev_attr_rx_crc_errors.attr,

    &dev_attr_rx_frame_errors.attr,

    &dev_attr_rx_fifo_errors.attr,

    &dev_attr_rx_missed_errors.attr,

    &dev_attr_tx_aborted_errors.attr,

    &dev_attr_tx_carrier_errors.attr,

    &dev_attr_tx_fifo_errors.attr,

    &dev_attr_tx_heartbeat_errors.attr,

    &dev_attr_tx_window_errors.attr,

    &dev_attr_rx_compressed.attr,

    &dev_attr_tx_compressed.attr,

    &dev_attr_rx_nohandler.attr,

    NULL

};

static struct attribute_group netstat_group = {

    .name = "statistics",

    .attrs = netstat_attrs,

};

netstat_show函数

点击(此处)折叠或打开#define __stringify_1(x...)    #x

#define __stringify(x...)    __stringify_1(x)

#define __ATTR_RO(_name) {                        \

    .attr    = { .name = __stringify(_name), .mode = S_IRUGO },    \

    .show    = _name##_show,                        \

}

#define DEVICE_ATTR_RO(_name) \

    struct device_attribute dev_attr_##_name = __ATTR_RO(_name)

struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,

                    struct rtnl_link_stats64 *storage)

{

    const struct net_device_ops *ops = dev->netdev_ops;

    if (ops->ndo_get_stats64) {

        memset(storage, 0, sizeof(*storage));

        ops->ndo_get_stats64(dev, storage);

    } else if (ops->ndo_get_stats) {

        netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev));

    } else {

        netdev_stats_to_stats64(storage, &dev->stats);

    }

    storage->rx_dropped += atomic_long_read(&dev->rx_dropped);

    storage->tx_dropped += atomic_long_read(&dev->tx_dropped);

    storage->rx_nohandler += atomic_long_read(&dev->rx_nohandler);

    return storage;

}

static ssize_t netstat_show(const struct device *d,

             struct device_attribute *attr, char *buf,

             unsigned long offset)

{

    struct net_device *dev = to_net_dev(d);

    ssize_t ret = -EINVAL;

    WARN_ON(offset > sizeof(struct rtnl_link_stats64) ||

            offset % sizeof(u64) != 0);

    read_lock(&dev_base_lock);

    if (dev_isalive(dev)) {

        struct rtnl_link_stats64 temp;

        const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);

        ret = sprintf(buf, fmt_u64, *(u64 *)(((u8 *) stats) + offset));

    }

    read_unlock(&dev_base_lock);

    return ret;

}

dev_get_stats

通过dev_get_stats()函数可以知道,如果网卡有注册ndo_get_stats64()函数或者ndo_get_stats()函数,则通过网卡驱动获取stats数据,否则直接通过dev->stats获取。

其他

net/core/dev.c
register_netdevice
net/core/net-sysfs.c
netdev_register_kobject()->
dev->groups = groups;
*groups++ = &netstat_group;
device_add()->device_add_attrs()->device_add_groups(dev->groups)->sysfs_create_groups() http://www.guc5469.cn/ http://www.dcj3647.cn/ http://www.utm9669.cn/ http://www.ahg7671.cn/ http://www.nxn1651.cn/ http://www.rrq5757.cn/ http://www.pbr1256.cn/ http://www.oai3459.cn/ http://www.vaj6107.cn/ http://www.xfc0942.cn/ http://www.evc2128.cn/ http://www.bwu7749.cn/ http://www.rmf4655.cn/ http://www.pyq8206.cn/ http://www.sdk5229.cn/ http://www.sez8143.cn/ http://www.tfn8353.cn/ http://www.uem3051.cn/ http://www.tza5452.cn/ http://www.epp9269.cn/ http://www.tsr7510.cn/ http://www.xhv3734.cn/ http://www.vrc9998.cn/ http://www.dsf5404.cn/ http://www.xjm6385.cn/ http://www.iaz1229.cn/ http://www.kcv6320.cn/ http://www.usl0022.cn/ http://www.abo8793.cn/ http://www.qeb9677.cn/ http://www.atx6995.cn/ http://www.buv6436.cn/ http://www.lll4952.cn/ http://www.cjx5965.cn/ http://www.otg2660.cn/ http://www.bmn9515.cn/ http://www.ewf1466.cn/ http://www.cbc3788.cn/ http://www.iqp5694.cn/ http://www.drr8954.cn/ http://www.blk2293.cn/ http://www.tjx3222.cn/ http://www.ksy2010.cn/ http://www.uva7574.cn/ http://www.epq3151.cn/ http://www.ofi3691.cn/ http://www.hwh7329.cn/ http://www.qta0411.cn/ http://www.oni7878.cn/ http://www.xlp3436.cn/ http://www.trm9066.cn/ http://www.wrq6652.cn/ http://www.oph4016.cn/ http://www.eis6490.cn/ http://www.xfq2422.cn/ http://www.tlj5370.cn/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: