ipmr.c (7ae9fb1b7ecbb5d85d07857943f677fd1a559b18) ipmr.c (e1d001fa5b477c4da46a29be1fcece91db7c7c6f)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * IP multicast routing support for mrouted 3.6/3.8
4 *
5 * (c) 1995 Alan Cox, <alan@lxorguk.ukuu.org.uk>
6 * Linux Consultancy and Custom Driver Development
7 *
8 * Fixes:

--- 1533 unchanged lines hidden (view full) ---

1542 ret = -ENOPROTOOPT;
1543 }
1544out_unlock:
1545 rtnl_unlock();
1546out:
1547 return ret;
1548}
1549
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * IP multicast routing support for mrouted 3.6/3.8
4 *
5 * (c) 1995 Alan Cox, <alan@lxorguk.ukuu.org.uk>
6 * Linux Consultancy and Custom Driver Development
7 *
8 * Fixes:

--- 1533 unchanged lines hidden (view full) ---

1542 ret = -ENOPROTOOPT;
1543 }
1544out_unlock:
1545 rtnl_unlock();
1546out:
1547 return ret;
1548}
1549
1550/* Execute if this ioctl is a special mroute ioctl */
1551int ipmr_sk_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
1552{
1553 switch (cmd) {
1554 /* These userspace buffers will be consumed by ipmr_ioctl() */
1555 case SIOCGETVIFCNT: {
1556 struct sioc_vif_req buffer;
1557
1558 return sock_ioctl_inout(sk, cmd, arg, &buffer,
1559 sizeof(buffer));
1560 }
1561 case SIOCGETSGCNT: {
1562 struct sioc_sg_req buffer;
1563
1564 return sock_ioctl_inout(sk, cmd, arg, &buffer,
1565 sizeof(buffer));
1566 }
1567 }
1568 /* return code > 0 means that the ioctl was not executed */
1569 return 1;
1570}
1571
1550/* Getsock opt support for the multicast routing system. */
1551int ip_mroute_getsockopt(struct sock *sk, int optname, sockptr_t optval,
1552 sockptr_t optlen)
1553{
1554 int olr;
1555 int val;
1556 struct net *net = sock_net(sk);
1557 struct mr_table *mrt;

--- 30 unchanged lines hidden (view full) ---

1588 if (copy_to_sockptr(optlen, &olr, sizeof(int)))
1589 return -EFAULT;
1590 if (copy_to_sockptr(optval, &val, olr))
1591 return -EFAULT;
1592 return 0;
1593}
1594
1595/* The IP multicast ioctl support routines. */
1572/* Getsock opt support for the multicast routing system. */
1573int ip_mroute_getsockopt(struct sock *sk, int optname, sockptr_t optval,
1574 sockptr_t optlen)
1575{
1576 int olr;
1577 int val;
1578 struct net *net = sock_net(sk);
1579 struct mr_table *mrt;

--- 30 unchanged lines hidden (view full) ---

1610 if (copy_to_sockptr(optlen, &olr, sizeof(int)))
1611 return -EFAULT;
1612 if (copy_to_sockptr(optval, &val, olr))
1613 return -EFAULT;
1614 return 0;
1615}
1616
1617/* The IP multicast ioctl support routines. */
1596int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
1618int ipmr_ioctl(struct sock *sk, int cmd, void *arg)
1597{
1619{
1598 struct sioc_sg_req sr;
1599 struct sioc_vif_req vr;
1600 struct vif_device *vif;
1601 struct mfc_cache *c;
1602 struct net *net = sock_net(sk);
1620 struct vif_device *vif;
1621 struct mfc_cache *c;
1622 struct net *net = sock_net(sk);
1623 struct sioc_vif_req *vr;
1624 struct sioc_sg_req *sr;
1603 struct mr_table *mrt;
1604
1605 mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
1606 if (!mrt)
1607 return -ENOENT;
1608
1609 switch (cmd) {
1610 case SIOCGETVIFCNT:
1625 struct mr_table *mrt;
1626
1627 mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT);
1628 if (!mrt)
1629 return -ENOENT;
1630
1631 switch (cmd) {
1632 case SIOCGETVIFCNT:
1611 if (copy_from_user(&vr, arg, sizeof(vr)))
1612 return -EFAULT;
1613 if (vr.vifi >= mrt->maxvif)
1633 vr = (struct sioc_vif_req *)arg;
1634 if (vr->vifi >= mrt->maxvif)
1614 return -EINVAL;
1635 return -EINVAL;
1615 vr.vifi = array_index_nospec(vr.vifi, mrt->maxvif);
1636 vr->vifi = array_index_nospec(vr->vifi, mrt->maxvif);
1616 rcu_read_lock();
1637 rcu_read_lock();
1617 vif = &mrt->vif_table[vr.vifi];
1618 if (VIF_EXISTS(mrt, vr.vifi)) {
1619 vr.icount = READ_ONCE(vif->pkt_in);
1620 vr.ocount = READ_ONCE(vif->pkt_out);
1621 vr.ibytes = READ_ONCE(vif->bytes_in);
1622 vr.obytes = READ_ONCE(vif->bytes_out);
1638 vif = &mrt->vif_table[vr->vifi];
1639 if (VIF_EXISTS(mrt, vr->vifi)) {
1640 vr->icount = READ_ONCE(vif->pkt_in);
1641 vr->ocount = READ_ONCE(vif->pkt_out);
1642 vr->ibytes = READ_ONCE(vif->bytes_in);
1643 vr->obytes = READ_ONCE(vif->bytes_out);
1623 rcu_read_unlock();
1624
1644 rcu_read_unlock();
1645
1625 if (copy_to_user(arg, &vr, sizeof(vr)))
1626 return -EFAULT;
1627 return 0;
1628 }
1629 rcu_read_unlock();
1630 return -EADDRNOTAVAIL;
1631 case SIOCGETSGCNT:
1646 return 0;
1647 }
1648 rcu_read_unlock();
1649 return -EADDRNOTAVAIL;
1650 case SIOCGETSGCNT:
1632 if (copy_from_user(&sr, arg, sizeof(sr)))
1633 return -EFAULT;
1651 sr = (struct sioc_sg_req *)arg;
1634
1635 rcu_read_lock();
1652
1653 rcu_read_lock();
1636 c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr);
1654 c = ipmr_cache_find(mrt, sr->src.s_addr, sr->grp.s_addr);
1637 if (c) {
1655 if (c) {
1638 sr.pktcnt = c->_c.mfc_un.res.pkt;
1639 sr.bytecnt = c->_c.mfc_un.res.bytes;
1640 sr.wrong_if = c->_c.mfc_un.res.wrong_if;
1656 sr->pktcnt = c->_c.mfc_un.res.pkt;
1657 sr->bytecnt = c->_c.mfc_un.res.bytes;
1658 sr->wrong_if = c->_c.mfc_un.res.wrong_if;
1641 rcu_read_unlock();
1659 rcu_read_unlock();
1642
1643 if (copy_to_user(arg, &sr, sizeof(sr)))
1644 return -EFAULT;
1645 return 0;
1646 }
1647 rcu_read_unlock();
1648 return -EADDRNOTAVAIL;
1649 default:
1650 return -ENOIOCTLCMD;
1651 }
1652}

--- 1516 unchanged lines hidden ---
1660 return 0;
1661 }
1662 rcu_read_unlock();
1663 return -EADDRNOTAVAIL;
1664 default:
1665 return -ENOIOCTLCMD;
1666 }
1667}

--- 1516 unchanged lines hidden ---