[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