From: Stephen Hemminger <stephen@networkplumber.org>
To: Stephen Hemminger <stephen@networkplumber.org>
Cc: Helmut Grohne <h.grohne@cygnusnetworks.de>,
David Miller <davem@davemloft.net>,
netdev@vger.kernel.org
Subject: [PATCH net-next 3/3] tuntap: allow overriding link statistics
Date: Wed, 24 Jul 2013 16:15:19 -0700 [thread overview]
Message-ID: <20130724161519.2bdbe528@nehalam.linuxnetplumber.net> (raw)
In-Reply-To: <20130724161156.4a8cf02b@nehalam.linuxnetplumber.net>
This patch adds new ioctl to allow overriding the link statistics
returned by the TUN device. This is useful when using tun device as a surrogate
for hardware or other software emulation. To use this application periodically
makes ioctl(TUNSETSTATS) to update statistics.
If TUNSETSTATS is not used the original software based statistics
are used.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
v2 - don't use exchange, use regular RCU
--- a/drivers/net/tun.c 2013-07-24 12:47:37.344206628 -0700
+++ b/drivers/net/tun.c 2013-07-24 16:14:00.964658040 -0700
@@ -152,6 +152,11 @@ struct tun_flow_entry {
unsigned long updated;
};
+struct tun_link_stats {
+ struct rtnl_link_stats64 link_stats;
+ struct rcu_head rcu;
+};
+
#define TUN_NUM_FLOW_ENTRIES 1024
/* Since the socket were moved to tun_file, to preserve the behavior of persist
@@ -190,6 +195,7 @@ struct tun_struct {
u32 speed;
u8 duplex;
struct tun_info info;
+ struct tun_link_stats __rcu *stats;
};
static inline u32 tun_hashfn(u32 rxhash)
@@ -803,6 +809,32 @@ static netdev_features_t tun_net_fix_fea
return (features & tun->set_features) | (features & ~TUN_USER_FEATURES);
}
+
+static struct rtnl_link_stats64 *
+tun_net_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage)
+{
+ struct tun_struct *tun = netdev_priv(dev);
+ struct tun_link_stats *stats;
+
+ rcu_read_lock();
+ stats = rcu_dereference(tun->stats);
+ if (stats) {
+ /* Stats received from device */
+ *storage = stats->link_stats;
+ rcu_read_unlock();
+
+ /* Add tunnel detected errors to mix */
+ storage->tx_dropped += dev->stats.tx_dropped;
+ storage->rx_dropped += dev->stats.rx_dropped;
+ storage->rx_frame_errors += dev->stats.rx_frame_errors;
+ return storage;
+ }
+ rcu_read_unlock();
+
+ netdev_stats_to_stats64(storage, &dev->stats);
+ return storage;
+}
+
#ifdef CONFIG_NET_POLL_CONTROLLER
static void tun_poll_controller(struct net_device *dev)
{
@@ -825,6 +857,7 @@ static const struct net_device_ops tun_n
.ndo_open = tun_net_open,
.ndo_stop = tun_net_close,
.ndo_start_xmit = tun_net_xmit,
+ .ndo_get_stats64 = tun_net_get_stats64,
.ndo_change_mtu = tun_net_change_mtu,
.ndo_fix_features = tun_net_fix_features,
.ndo_select_queue = tun_select_queue,
@@ -838,6 +871,7 @@ static const struct net_device_ops tap_n
.ndo_open = tun_net_open,
.ndo_stop = tun_net_close,
.ndo_start_xmit = tun_net_xmit,
+ .ndo_get_stats64 = tun_net_get_stats64,
.ndo_change_mtu = tun_net_change_mtu,
.ndo_fix_features = tun_net_fix_features,
.ndo_set_rx_mode = tun_net_mclist,
@@ -1422,9 +1456,13 @@ out:
static void tun_free_netdev(struct net_device *dev)
{
struct tun_struct *tun = netdev_priv(dev);
+ struct tun_link_stats *stats;
BUG_ON(!(list_empty(&tun->disabled)));
tun_flow_uninit(tun);
+ stats = rtnl_dereference(tun->stats);
+ if (stats)
+ kfree_rcu(stats, rcu);
security_tun_dev_free_security(tun->security);
free_netdev(dev);
}
@@ -1886,6 +1924,28 @@ unlock:
return ret;
}
+static int tun_set_stats(struct tun_struct *tun, void __user *argp)
+{
+ struct tun_link_stats *stats, *old;
+
+ stats = kmalloc(sizeof(struct tun_link_stats), GFP_KERNEL);
+ if (!stats)
+ return -ENOMEM;
+
+ if (copy_from_user(&stats->link_stats, argp,
+ sizeof(struct rtnl_link_stats64))) {
+ kfree(stats);
+ return -EFAULT;
+ }
+
+ old = rtnl_dereference(tun->stats);
+ rcu_assign_pointer(tun->stats, stats);
+ if (old)
+ kfree_rcu(old, rcu);
+
+ return 0;
+}
+
static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
unsigned long arg, int ifreq_len)
{
@@ -2108,6 +2168,11 @@ static long __tun_chr_ioctl(struct file
tun->info = info;
break;
}
+
+ case TUNSETSTATS:
+ ret = tun_set_stats(tun, argp);
+ break;
+
default:
ret = -EINVAL;
break;
@@ -2137,6 +2202,7 @@ static long tun_chr_compat_ioctl(struct
case TUNGETSNDBUF:
case TUNSETSNDBUF:
case TUNSETINFO:
+ case TUNSETSTATS:
case SIOCGIFHWADDR:
case SIOCSIFHWADDR:
arg = (unsigned long)compat_ptr(arg);
--- a/include/uapi/linux/if_tun.h 2013-07-24 12:47:37.344206628 -0700
+++ b/include/uapi/linux/if_tun.h 2013-07-24 12:47:37.352206531 -0700
@@ -57,6 +57,7 @@
#define TUNSETVNETHDRSZ _IOW('T', 216, int)
#define TUNSETQUEUE _IOW('T', 217, int)
#define TUNSETINFO _IOW('T', 219, struct tun_info)
+#define TUNSETSTATS _IOW('T', 220, struct rtnl_link_stats64)
/* TUNSETIFF ifr flags */
#define IFF_TUN 0x0001
next prev parent reply other threads:[~2013-07-24 23:15 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-24 23:11 [PATCH net-next 1/3] tuntap: allow changing ethtool speed (v2) Stephen Hemminger
2013-07-24 23:13 ` [PATCH net-next 2/3] tuntap: allow overriding ethtool driver info Stephen Hemminger
2013-07-24 23:48 ` Ben Hutchings
2013-07-25 0:16 ` Stephen Hemminger
2013-07-25 21:19 ` Ben Hutchings
2013-07-25 21:32 ` Stephen Hemminger
2013-07-25 21:36 ` Ben Hutchings
2013-07-25 21:56 ` Stephen Hemminger
2013-07-24 23:15 ` Stephen Hemminger [this message]
2013-07-24 23:40 ` [PATCH net-next 1/3] tuntap: allow changing ethtool speed (v2) Ben Hutchings
2013-07-25 0:17 ` Stephen Hemminger
2013-07-25 0:29 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130724161519.2bdbe528@nehalam.linuxnetplumber.net \
--to=stephen@networkplumber.org \
--cc=davem@davemloft.net \
--cc=h.grohne@cygnusnetworks.de \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).