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 <vsement...@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 <vsement...@virtuozzo.com>
    Reviewed-by: Cyrill Gorcunov <gorcu...@openvz.org>
    Acked-by: Konstantin Khorenko <khore...@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.
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to