[Devel] [PATCH RHEL7 COMMIT] ve/net: introduce TAP accounting
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Oct 15 07:56:47 PDT 2015
The commit is pushed to "branch-rh7-3.10.0-229.7.2.vz7.8.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-229.7.2.vz7.8.6
------>
commit b59e089eb2d2fdc939e54abb656cd5b7a2ad500e
Author: Vladimir Sementsov-Ogievskiy <vsementsov at virtuozzo.com>
Date: Thu Oct 15 18:56:47 2015 +0400
ve/net: introduce TAP accounting
Add ve accounting to tun/tap devices. New ioctl should be called to
attach/create ve stat to tun/tap.
https://jira.sw.ru/browse/PSBM-27713
Note: TUN accounting is not tested for now and disabled in this commit.
only TAP accounting is allowed for now.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov at virtuozzo.com>
Reviewed-by: Cyrill Gorcunov <gorcunov at openvz.org>
Acked-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
drivers/net/tun.c | 68 ++++++++++++++++++++++++++++++++++++++++++++-
include/uapi/linux/if_tun.h | 9 ++++++
kernel/Kconfig.openvz | 7 +++++
3 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 392d701..4f7eee9 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -71,6 +71,10 @@
#include <asm/uaccess.h>
+#ifdef CONFIG_VE_TUNTAP_ACCOUNTING
+#include <linux/vznetstat.h>
+#endif /* CONFIG_VE_TUNTAP_ACCOUNTING */
+
/* Uncomment to enable debugging */
/* #define TUN_DEBUG 1 */
@@ -190,6 +194,9 @@ struct tun_struct {
struct list_head disabled;
void *security;
u32 flow_count;
+#ifdef CONFIG_VE_TUNTAP_ACCOUNTING
+ struct venet_stat *vestat;
+#endif /* CONFIG_VE_TUNTAP_ACCOUNTING */
};
static inline u32 tun_hashfn(u32 rxhash)
@@ -1241,6 +1248,12 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
tun->dev->stats.rx_packets++;
tun->dev->stats.rx_bytes += len;
+#ifdef CONFIG_VE_TUNTAP_ACCOUNTING
+ if (tun->vestat) {
+ venet_acct_classify_add_outgoing(tun->vestat, skb);
+ }
+#endif /* CONFIG_VE_TUNTAP_ACCOUNTING */
+
tun_flow_update(tun, rxhash, tfile);
return total_len;
}
@@ -1344,6 +1357,12 @@ static ssize_t tun_put_user(struct tun_struct *tun,
tun->dev->stats.tx_packets++;
tun->dev->stats.tx_bytes += len;
+#ifdef CONFIG_VE_TUNTAP_ACCOUNTING
+ if (tun->vestat) {
+ venet_acct_classify_add_incoming(tun->vestat, skb);
+ }
+#endif /* CONFIG_VE_TUNTAP_ACCOUNTING */
+
return total;
}
@@ -1428,6 +1447,14 @@ static void tun_free_netdev(struct net_device *dev)
BUG_ON(!(list_empty(&tun->disabled)));
tun_flow_uninit(tun);
security_tun_dev_free_security(tun->security);
+
+#ifdef CONFIG_VE_TUNTAP_ACCOUNTING
+ if (tun->vestat) {
+ venet_acct_put_stat(tun->vestat);
+ tun->vestat = NULL;
+ }
+#endif /* CONFIG_VE_TUNTAP_ACCOUNTING */
+
free_netdev(dev);
}
@@ -1892,11 +1919,43 @@ unlock:
return ret;
}
+#ifdef CONFIG_VE_TUNTAP_ACCOUNTING
+/* setacctid_ioctl should be called under rtnl_lock */
+static long setacctid_ioctl(struct file *file, void __user *argp)
+{
+ struct tun_file *tfile = file->private_data;
+ struct tun_acctid info;
+ struct net_device *dev;
+ struct tun_struct *tun;
+
+ if (copy_from_user(&info, argp, sizeof(info)))
+ return -EFAULT;
+
+ dev = __dev_get_by_name(tfile->net, info.ifname);
+ if (dev == NULL)
+ return -ENOENT;
+
+ /* This check may be dropped to allow tun devices */
+ if (dev->netdev_ops != &tap_netdev_ops)
+ return -EINVAL;
+
+ tun = netdev_priv(dev);
+ if (tun->vestat) {
+ venet_acct_put_stat(tun->vestat);
+ }
+ tun->vestat = venet_acct_find_create_stat(info.acctid);
+ if (tun->vestat == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+#endif /* CONFIG_VE_TUNTAP_ACCOUNTING */
+
static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
unsigned long arg, int ifreq_len)
{
struct tun_file *tfile = file->private_data;
- struct tun_struct *tun;
+ struct tun_struct *tun = NULL;
void __user* argp = (void __user*)arg;
struct ifreq ifr;
kuid_t owner;
@@ -1925,6 +1984,13 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
ret = 0;
rtnl_lock();
+#ifdef CONFIG_VE_TUNTAP_ACCOUNTING
+ if (cmd == TUNSETACCTID) {
+ ret = setacctid_ioctl(file, argp);
+ goto unlock;
+ }
+#endif /* CONFIG_VE_TUNTAP_ACCOUNTING */
+
tun = __tun_get(tfile);
if (cmd == TUNSETIFF && !tun) {
ifr.ifr_name[IFNAMSIZ-1] = '\0';
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h
index c80d152..81e791e 100644
--- a/include/uapi/linux/if_tun.h
+++ b/include/uapi/linux/if_tun.h
@@ -59,6 +59,9 @@
#define TUNSETIFINDEX _IOW('T', 218, unsigned int)
#define TUNGETFILTER _IOR('T', 219, struct sock_fprog)
+/* CONFIG_VE_TUNTAP_ACCOUNTING should be set */
+#define TUNSETACCTID _IOW('T', 300, struct tun_acctid)
+
/* TUNSETIFF ifr flags */
#define IFF_TUN 0x0001
#define IFF_TAP 0x0002
@@ -103,4 +106,10 @@ struct tun_filter {
__u8 addr[0][ETH_ALEN];
};
+/* used as TUNSETACCTID ioctl parameter */
+struct tun_acctid {
+ char ifname[IFNAMSIZ];
+ __u32 acctid;
+};
+
#endif /* _UAPI__IF_TUN_H */
diff --git a/kernel/Kconfig.openvz b/kernel/Kconfig.openvz
index 2465d82..5f45e5b 100644
--- a/kernel/Kconfig.openvz
+++ b/kernel/Kconfig.openvz
@@ -103,3 +103,10 @@ config VZ_IOLIMIT
default m
help
This option provides io-limiting module.
+
+config VE_TUNTAP_ACCOUNTING
+ bool "Accounting for tun/tap devices"
+ depends on VE_NETDEV_ACCOUNTING
+ default y
+ help
+ This option enables accounting for tun/tap devices.
More information about the Devel
mailing list