net: split out SIOCDEVPRIVATE handling from dev_ioctl
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> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2fba2eae30
commit
b9067f5dc4
@ -222,6 +222,13 @@ ndo_do_ioctl:
|
|||||||
Synchronization: rtnl_lock() semaphore.
|
Synchronization: rtnl_lock() semaphore.
|
||||||
Context: process
|
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:
|
ndo_get_stats:
|
||||||
Synchronization: rtnl_lock() semaphore, dev_base_lock rwlock, or RCU.
|
Synchronization: rtnl_lock() semaphore, dev_base_lock rwlock, or RCU.
|
||||||
Context: atomic (can't sleep under rwlock or RCU)
|
Context: atomic (can't sleep under rwlock or RCU)
|
||||||
|
@ -1361,6 +1361,9 @@ struct net_device_ops {
|
|||||||
int (*ndo_validate_addr)(struct net_device *dev);
|
int (*ndo_validate_addr)(struct net_device *dev);
|
||||||
int (*ndo_do_ioctl)(struct net_device *dev,
|
int (*ndo_do_ioctl)(struct net_device *dev,
|
||||||
struct ifreq *ifr, int cmd);
|
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,
|
int (*ndo_set_config)(struct net_device *dev,
|
||||||
struct ifmap *map);
|
struct ifmap *map);
|
||||||
int (*ndo_change_mtu)(struct net_device *dev,
|
int (*ndo_change_mtu)(struct net_device *dev,
|
||||||
|
@ -259,6 +259,23 @@ static int dev_do_ioctl(struct net_device *dev,
|
|||||||
return err;
|
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()
|
* 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
|
* Unknown or private ioctl
|
||||||
*/
|
*/
|
||||||
default:
|
default:
|
||||||
if ((cmd >= SIOCDEVPRIVATE &&
|
if (cmd >= SIOCDEVPRIVATE &&
|
||||||
cmd <= SIOCDEVPRIVATE + 15) ||
|
cmd <= SIOCDEVPRIVATE + 15)
|
||||||
cmd == SIOCBONDENSLAVE ||
|
return dev_siocdevprivate(dev, ifr, cmd);
|
||||||
|
|
||||||
|
if (cmd == SIOCBONDENSLAVE ||
|
||||||
cmd == SIOCBONDRELEASE ||
|
cmd == SIOCBONDRELEASE ||
|
||||||
cmd == SIOCBONDSETHWADDR ||
|
cmd == SIOCBONDSETHWADDR ||
|
||||||
cmd == SIOCBONDSLAVEINFOQUERY ||
|
cmd == SIOCBONDSLAVEINFOQUERY ||
|
||||||
|
Loading…
Reference in New Issue
Block a user