Source
4
4
#include <net/rtnetlink.h>
5
5
#include <net/sock.h>
6
6
#include <net/af_vsock.h>
7
7
#include <uapi/linux/vsockmon.h>
8
8
#include <linux/virtio_vsock.h>
9
9
10
10
/* Virtio transport max packet size plus header */
11
11
#define DEFAULT_MTU (VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + \
12
12
sizeof(struct af_vsockmon_hdr))
13
13
14
-
struct pcpu_lstats {
15
-
u64 rx_packets;
16
-
u64 rx_bytes;
17
-
struct u64_stats_sync syncp;
18
-
};
19
-
20
14
static int vsockmon_dev_init(struct net_device *dev)
21
15
{
22
16
dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats);
23
17
if (!dev->lstats)
24
18
return -ENOMEM;
25
19
return 0;
26
20
}
27
21
28
22
static void vsockmon_dev_uninit(struct net_device *dev)
29
23
{
49
43
50
44
return vsock_remove_tap(&vsockmon->vt);
51
45
}
52
46
53
47
static netdev_tx_t vsockmon_xmit(struct sk_buff *skb, struct net_device *dev)
54
48
{
55
49
int len = skb->len;
56
50
struct pcpu_lstats *stats = this_cpu_ptr(dev->lstats);
57
51
58
52
u64_stats_update_begin(&stats->syncp);
59
-
stats->rx_bytes += len;
60
-
stats->rx_packets++;
53
+
stats->bytes += len;
54
+
stats->packets++;
61
55
u64_stats_update_end(&stats->syncp);
62
56
63
57
dev_kfree_skb(skb);
64
58
65
59
return NETDEV_TX_OK;
66
60
}
67
61
68
62
static void
69
63
vsockmon_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
70
64
{
73
67
74
68
for_each_possible_cpu(i) {
75
69
const struct pcpu_lstats *vstats;
76
70
u64 tbytes, tpackets;
77
71
unsigned int start;
78
72
79
73
vstats = per_cpu_ptr(dev->lstats, i);
80
74
81
75
do {
82
76
start = u64_stats_fetch_begin_irq(&vstats->syncp);
83
-
tbytes = vstats->rx_bytes;
84
-
tpackets = vstats->rx_packets;
77
+
tbytes = vstats->bytes;
78
+
tpackets = vstats->packets;
85
79
} while (u64_stats_fetch_retry_irq(&vstats->syncp, start));
86
80
87
81
packets += tpackets;
88
82
bytes += tbytes;
89
83
}
90
84
91
85
stats->rx_packets = packets;
92
86
stats->tx_packets = 0;
93
87
94
88
stats->rx_bytes = bytes;