diff options
author | David S. Miller <davem@davemloft.net> | 2011-02-04 04:24:28 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-04 04:24:28 +0300 |
commit | ca6b8bb097c8e0ab6bce4fa04584074dee17c0d9 (patch) | |
tree | 4d4892f421fbe0edfb03fab640521d01c8540c52 /net | |
parent | 0033d5ad27a6db33a55ff39951d3ec61a8c13b89 (diff) | |
download | linux-ca6b8bb097c8e0ab6bce4fa04584074dee17c0d9.tar.xz |
net: Support compat SIOCGETVIFCNT ioctl in ipv4.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/ipmr.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index fce10a080bd6..8b65a12654e7 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1444,9 +1444,19 @@ struct compat_sioc_sg_req { compat_ulong_t wrong_if; }; +struct compat_sioc_vif_req { + vifi_t vifi; /* Which iface */ + compat_ulong_t icount; + compat_ulong_t ocount; + compat_ulong_t ibytes; + compat_ulong_t obytes; +}; + int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) { struct compat_sioc_sg_req sr; + struct compat_sioc_vif_req vr; + struct vif_device *vif; struct mfc_cache *c; struct net *net = sock_net(sk); struct mr_table *mrt; @@ -1456,6 +1466,26 @@ int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) return -ENOENT; switch (cmd) { + case SIOCGETVIFCNT: + if (copy_from_user(&vr, arg, sizeof(vr))) + return -EFAULT; + if (vr.vifi >= mrt->maxvif) + return -EINVAL; + read_lock(&mrt_lock); + vif = &mrt->vif_table[vr.vifi]; + if (VIF_EXISTS(mrt, vr.vifi)) { + vr.icount = vif->pkt_in; + vr.ocount = vif->pkt_out; + vr.ibytes = vif->bytes_in; + vr.obytes = vif->bytes_out; + read_unlock(&mrt_lock); + + if (copy_to_user(arg, &vr, sizeof(vr))) + return -EFAULT; + return 0; + } + read_unlock(&mrt_lock); + return -EADDRNOTAVAIL; case SIOCGETSGCNT: if (copy_from_user(&sr, arg, sizeof(sr))) return -EFAULT; |