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