Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Data gathering module for Linux-VM Monitor Stream, Stage 1.
0004  * Collects accumulated network statistics (Packets received/transmitted,
0005  * dropped, errors, ...).
0006  *
0007  * Copyright IBM Corp. 2003, 2006
0008  *
0009  * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
0010  */
0011 
0012 #include <linux/module.h>
0013 #include <linux/init.h>
0014 #include <linux/errno.h>
0015 #include <linux/kernel_stat.h>
0016 #include <linux/netdevice.h>
0017 #include <net/net_namespace.h>
0018 
0019 #include "appldata.h"
0020 
0021 
0022 /*
0023  * Network data
0024  *
0025  * This is accessed as binary data by z/VM. If changes to it can't be avoided,
0026  * the structure version (product ID, see appldata_base.c) needs to be changed
0027  * as well and all documentation and z/VM applications using it must be updated.
0028  */
0029 struct appldata_net_sum_data {
0030     u64 timestamp;
0031     u32 sync_count_1;   /* after VM collected the record data, */
0032     u32 sync_count_2;   /* sync_count_1 and sync_count_2 should be the
0033                    same. If not, the record has been updated on
0034                    the Linux side while VM was collecting the
0035                    (possibly corrupt) data */
0036 
0037     u32 nr_interfaces;  /* nr. of network interfaces being monitored */
0038 
0039     u32 padding;        /* next value is 64-bit aligned, so these */
0040                 /* 4 byte would be padded out by compiler */
0041 
0042     u64 rx_packets;     /* total packets received        */
0043     u64 tx_packets;     /* total packets transmitted     */
0044     u64 rx_bytes;       /* total bytes received          */
0045     u64 tx_bytes;       /* total bytes transmitted       */
0046     u64 rx_errors;      /* bad packets received          */
0047     u64 tx_errors;      /* packet transmit problems      */
0048     u64 rx_dropped;     /* no space in linux buffers     */
0049     u64 tx_dropped;     /* no space available in linux   */
0050     u64 collisions;     /* collisions while transmitting */
0051 } __packed;
0052 
0053 
0054 /*
0055  * appldata_get_net_sum_data()
0056  *
0057  * gather accumulated network statistics
0058  */
0059 static void appldata_get_net_sum_data(void *data)
0060 {
0061     int i;
0062     struct appldata_net_sum_data *net_data;
0063     struct net_device *dev;
0064     unsigned long rx_packets, tx_packets, rx_bytes, tx_bytes, rx_errors,
0065             tx_errors, rx_dropped, tx_dropped, collisions;
0066 
0067     net_data = data;
0068     net_data->sync_count_1++;
0069 
0070     i = 0;
0071     rx_packets = 0;
0072     tx_packets = 0;
0073     rx_bytes   = 0;
0074     tx_bytes   = 0;
0075     rx_errors  = 0;
0076     tx_errors  = 0;
0077     rx_dropped = 0;
0078     tx_dropped = 0;
0079     collisions = 0;
0080 
0081     rcu_read_lock();
0082     for_each_netdev_rcu(&init_net, dev) {
0083         const struct rtnl_link_stats64 *stats;
0084         struct rtnl_link_stats64 temp;
0085 
0086         stats = dev_get_stats(dev, &temp);
0087         rx_packets += stats->rx_packets;
0088         tx_packets += stats->tx_packets;
0089         rx_bytes   += stats->rx_bytes;
0090         tx_bytes   += stats->tx_bytes;
0091         rx_errors  += stats->rx_errors;
0092         tx_errors  += stats->tx_errors;
0093         rx_dropped += stats->rx_dropped;
0094         tx_dropped += stats->tx_dropped;
0095         collisions += stats->collisions;
0096         i++;
0097     }
0098     rcu_read_unlock();
0099 
0100     net_data->nr_interfaces = i;
0101     net_data->rx_packets = rx_packets;
0102     net_data->tx_packets = tx_packets;
0103     net_data->rx_bytes   = rx_bytes;
0104     net_data->tx_bytes   = tx_bytes;
0105     net_data->rx_errors  = rx_errors;
0106     net_data->tx_errors  = tx_errors;
0107     net_data->rx_dropped = rx_dropped;
0108     net_data->tx_dropped = tx_dropped;
0109     net_data->collisions = collisions;
0110 
0111     net_data->timestamp = get_tod_clock();
0112     net_data->sync_count_2++;
0113 }
0114 
0115 
0116 static struct appldata_ops ops = {
0117     .name      = "net_sum",
0118     .record_nr = APPLDATA_RECORD_NET_SUM_ID,
0119     .size      = sizeof(struct appldata_net_sum_data),
0120     .callback  = &appldata_get_net_sum_data,
0121     .owner     = THIS_MODULE,
0122     .mod_lvl   = {0xF0, 0xF0},      /* EBCDIC "00" */
0123 };
0124 
0125 
0126 /*
0127  * appldata_net_init()
0128  *
0129  * init data, register ops
0130  */
0131 static int __init appldata_net_init(void)
0132 {
0133     int ret;
0134 
0135     ops.data = kzalloc(sizeof(struct appldata_net_sum_data), GFP_KERNEL);
0136     if (!ops.data)
0137         return -ENOMEM;
0138 
0139     ret = appldata_register_ops(&ops);
0140     if (ret)
0141         kfree(ops.data);
0142 
0143     return ret;
0144 }
0145 
0146 /*
0147  * appldata_net_exit()
0148  *
0149  * unregister ops
0150  */
0151 static void __exit appldata_net_exit(void)
0152 {
0153     appldata_unregister_ops(&ops);
0154     kfree(ops.data);
0155 }
0156 
0157 
0158 module_init(appldata_net_init);
0159 module_exit(appldata_net_exit);
0160 
0161 MODULE_LICENSE("GPL");
0162 MODULE_AUTHOR("Gerald Schaefer");
0163 MODULE_DESCRIPTION("Linux-VM Monitor Stream, accumulated network statistics");