lkml.org 
[lkml]   [2021]   [Jul]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH net-next v3 01/31] net: split out SIOCDEVPRIVATE handling from dev_ioctl
    Date
    From: Arnd Bergmann <arnd@arndb.de>

    SIOCDEVPRIVATE ioctl commands are mainly used in really old
    drivers, and they have a number of problems:

    - They hide behind the normal .ndo_do_ioctl function that
    is also used for other things in modern drivers, so it's
    hard to spot a driver that actually uses one of these

    - Since drivers use a number different calling conventions,
    it is impossible to support compat mode for them in
    a generic way.

    - With all drivers using the same 16 commands codes, there
    is no way to introspect the data being passed through
    things like strace.

    Add a new net_device_ops callback pointer, to address the
    first two of these. Separating them from .ndo_do_ioctl
    makes it easy to grep for drivers with a .ndo_siocdevprivate
    callback, and the unwieldy name hopefully makes it easier
    to spot in code review.

    By passing the ifreq structure and the ifr_data pointer
    separately, it is no longer necessary to overload these,
    and the driver can use either one for a given command.

    Cc: Cong Wang <cong.wang@bytedance.com>
    Signed-off-by: Arnd Bergmann <arnd@arndb.de>
    ---
    Documentation/networking/netdevices.rst | 7 +++++++
    include/linux/netdevice.h | 3 +++
    net/core/dev_ioctl.c | 25 ++++++++++++++++++++++---
    3 files changed, 32 insertions(+), 3 deletions(-)

    diff --git a/Documentation/networking/netdevices.rst b/Documentation/networking/netdevices.rst
    index 17bdcb746dcf..02f1faac839a 100644
    --- a/Documentation/networking/netdevices.rst
    +++ b/Documentation/networking/netdevices.rst
    @@ -222,6 +222,13 @@ ndo_do_ioctl:
    Synchronization: rtnl_lock() semaphore.
    Context: process

    +ndo_siocdevprivate:
    + Synchronization: rtnl_lock() semaphore.
    + Context: process
    +
    + This is used to implement SIOCDEVPRIVATE ioctl helpers.
    + These should not be added to new drivers, so don't use.
    +
    ndo_get_stats:
    Synchronization: rtnl_lock() semaphore, dev_base_lock rwlock, or RCU.
    Context: atomic (can't sleep under rwlock or RCU)
    diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
    index c871dc223dfa..670e1a8e5928 100644
    --- a/include/linux/netdevice.h
    +++ b/include/linux/netdevice.h
    @@ -1361,6 +1361,9 @@ struct net_device_ops {
    int (*ndo_validate_addr)(struct net_device *dev);
    int (*ndo_do_ioctl)(struct net_device *dev,
    struct ifreq *ifr, int cmd);
    + int (*ndo_siocdevprivate)(struct net_device *dev,
    + struct ifreq *ifr,
    + void __user *data, int cmd);
    int (*ndo_set_config)(struct net_device *dev,
    struct ifmap *map);
    int (*ndo_change_mtu)(struct net_device *dev,
    diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
    index 950e2fe5d56a..75e3e340d884 100644
    --- a/net/core/dev_ioctl.c
    +++ b/net/core/dev_ioctl.c
    @@ -259,6 +259,23 @@ static int dev_do_ioctl(struct net_device *dev,
    return err;
    }

    +static int dev_siocdevprivate(struct net_device *dev,
    + struct ifreq *ifr, unsigned int cmd)
    +{
    + const struct net_device_ops *ops = dev->netdev_ops;
    + void __user *data = ifr->ifr_data;
    +
    + if (ops->ndo_siocdevprivate) {
    + if (netif_device_present(dev))
    + return ops->ndo_siocdevprivate(dev, ifr, data, cmd);
    + else
    + return -ENODEV;
    + }
    +
    + /* fall back to do_ioctl for drivers not yet converted */
    + return dev_do_ioctl(dev, ifr, cmd);
    +}
    +
    /*
    * Perform the SIOCxIFxxx calls, inside rtnl_lock()
    */
    @@ -336,9 +353,11 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
    * Unknown or private ioctl
    */
    default:
    - if ((cmd >= SIOCDEVPRIVATE &&
    - cmd <= SIOCDEVPRIVATE + 15) ||
    - cmd == SIOCBONDENSLAVE ||
    + if (cmd >= SIOCDEVPRIVATE &&
    + cmd <= SIOCDEVPRIVATE + 15)
    + return dev_siocdevprivate(dev, ifr, cmd);
    +
    + if (cmd == SIOCBONDENSLAVE ||
    cmd == SIOCBONDRELEASE ||
    cmd == SIOCBONDSETHWADDR ||
    cmd == SIOCBONDSLAVEINFOQUERY ||
    --
    2.29.2
    \
     
     \ /
      Last update: 2021-07-27 15:47    [W:4.140 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site