aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/ipmr.c30
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 {
1444 compat_ulong_t wrong_if; 1444 compat_ulong_t wrong_if;
1445}; 1445};
1446 1446
1447struct compat_sioc_vif_req {
1448 vifi_t vifi; /* Which iface */
1449 compat_ulong_t icount;
1450 compat_ulong_t ocount;
1451 compat_ulong_t ibytes;
1452 compat_ulong_t obytes;
1453};
1454
1447int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) 1455int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
1448{ 1456{
1449 struct compat_sioc_sg_req sr; 1457 struct compat_sioc_sg_req sr;
1458 struct compat_sioc_vif_req vr;
1459 struct vif_device *vif;
1450 struct mfc_cache *c; 1460 struct mfc_cache *c;
1451 struct net *net = sock_net(sk); 1461 struct net *net = sock_net(sk);
1452 struct mr_table *mrt; 1462 struct mr_table *mrt;
@@ -1456,6 +1466,26 @@ int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
1456 return -ENOENT; 1466 return -ENOENT;
1457 1467
1458 switch (cmd) { 1468 switch (cmd) {
1469 case SIOCGETVIFCNT:
1470 if (copy_from_user(&vr, arg, sizeof(vr)))
1471 return -EFAULT;
1472 if (vr.vifi >= mrt->maxvif)
1473 return -EINVAL;
1474 read_lock(&mrt_lock);
1475 vif = &mrt->vif_table[vr.vifi];
1476 if (VIF_EXISTS(mrt, vr.vifi)) {
1477 vr.icount = vif->pkt_in;
1478 vr.ocount = vif->pkt_out;
1479 vr.ibytes = vif->bytes_in;
1480 vr.obytes = vif->bytes_out;
1481 read_unlock(&mrt_lock);
1482
1483 if (copy_to_user(arg, &vr, sizeof(vr)))
1484 return -EFAULT;
1485 return 0;
1486 }
1487 read_unlock(&mrt_lock);
1488 return -EADDRNOTAVAIL;
1459 case SIOCGETSGCNT: 1489 case SIOCGETSGCNT:
1460 if (copy_from_user(&sr, arg, sizeof(sr))) 1490 if (copy_from_user(&sr, arg, sizeof(sr)))
1461 return -EFAULT; 1491 return -EFAULT;