net: separate SIOCGIFCONF handling from dev_ioctl()
Only two of dev_ioctl() callers may pass SIOCGIFCONF to it. Separating that codepath from the rest of dev_ioctl() allows both to simplify dev_ioctl() itself (all other cases work with struct ifreq *) *and* seriously simplify the compat side of that beast: all it takes is passing to inet_gifconf() an extra argument - the size of individual records (sizeof(struct ifreq) or sizeof(struct compat_ifreq)). With dev_ifconf() called directly from sock_do_ioctl()/compat_dev_ifconf() that's easy to arrange. As the result, compat side of SIOCGIFCONF doesn't need any allocations, copy_in_user() back and forth, etc. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
@@ -2761,7 +2761,8 @@ static inline bool dev_validate_header(const struct net_device *dev,
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len);
|
||||
typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr,
|
||||
int len, int size);
|
||||
int register_gifconf(unsigned int family, gifconf_func_t *gifconf);
|
||||
static inline int unregister_gifconf(unsigned int family)
|
||||
{
|
||||
@@ -3315,6 +3316,7 @@ void netdev_rx_handler_unregister(struct net_device *dev);
|
||||
|
||||
bool dev_valid_name(const char *name);
|
||||
int dev_ioctl(struct net *net, unsigned int cmd, void __user *);
|
||||
int dev_ifconf(struct net *net, struct ifconf *, int);
|
||||
int dev_ethtool(struct net *net, struct ifreq *);
|
||||
unsigned int dev_get_flags(const struct net_device *);
|
||||
int __dev_change_flags(struct net_device *, unsigned int flags);
|
||||
|
Reference in New Issue
Block a user