diff options
Diffstat (limited to 'net/ipv4/ipmr.c')
-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 { | |||
1444 | compat_ulong_t wrong_if; | 1444 | compat_ulong_t wrong_if; |
1445 | }; | 1445 | }; |
1446 | 1446 | ||
1447 | struct 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 | |||
1447 | int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) | 1455 | int 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; |